JS闭包

2020-03-24  本文已影响0人  罂粟1995

闭包,几乎是面试必考。

什么是闭包

一个函数的作用域是定义作用域而非执行作用域。常见的表现形式是函数包含在其他函数之中,能够读取其他函数内部的变量。
每当声明了一个函数,它就产生了一个闭包域,凡是在闭包域内声明的变量或方法,外部无法直接访问,闭包域却可以访问外部的变量或方法。

闭包的应用:数据缓存

如果有一个函数,每次计算的时候会耗费很大的性能,我们就可以利用闭包数据缓存来进行优化。
将函数的计算结果储存在缓存中,当下次计算时,先查看缓存有没有相应的结果值,如果有,取缓存值,如果没有,执行函数,并保存缓存值。记得控制缓存的大小。

代码示例:
    var CachedSearchData = (function () {
          var cache = {};
          var count = [];
          return {
              getSearchData: function (id) {
                  if (id in cache) {//如果结果在缓存中
                      return cache[id];//直接返回缓存中的对象
                  } else {
                      //到数据库中查找
                      //存缓存
                      cache[id] = id;
                      if(count.indexOf(id) == -1){
                           count.push(id);
                      }
                      if(count.length > 100){
                           delete cache[count.shift()];    
                      }   
                      return "not in cache";
                  }
              },
          };
      })();

      console.log(CachedSearchData.getSearchData(77));//输出not in cache
      console.log(CachedSearchData.getSearchData(77));//输出77

闭包的应用:匿名自执行函数

有的函数只需要执行一遍,例如UI的初始化;创建一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,这种机制不会污染全局对象。

(function () {
      //自执行函数
})();

闭包的应用:实现封装

在某个对象之外无法访问它的内部变量,而是提供闭包的形式来访问。

代码示例:
var person = function() {
   var name = "default";       
      
   return {    
      getName : function(){    
          return name;    
      },    
      setName : function(newName){    
          name = newName;    
      }    
   }    
}()

常见面试题:

  1. 实现一个函数a(),第一次执行时输出1,第二次执行时输出2,第三次执行时输出1,第四次执行时输出2,第五次执行时输出1……如此循环。
       var a = (function(){
          var temp = 1;
            return function () {
                console.log(temp);
                temp == 1 ? temp = 2 : temp = 1;
            }
            
        })();

        a() //输出1
        a() //输出2
        a() //输出1
        a() //输出2
  1. 实现循环中的延时打印。
       for(var i = 1; i < 4; i++) {
            setTimeout(
                (function(i){
                    return function () {
                        console.log(i);
                    }
                })(i),
               300
            )
        }
//打印:1 2 3
  1. 获取多个元素并依次添加点击事件。
var op = document.querySelectorAll("p");
for (var j = 0; j < op.length; j++) {
  op[j].onclick = (function(j) {
    return function() {
      alert(j);
    };
  })(j);
}
上一篇 下一篇

猜你喜欢

热点阅读