javascript之闭包

2018-12-25  本文已影响0人  darayo

什么是闭包(Closure)?

是指有权限访问另一个函数作用域中的变量的函数。概念看起来比较简单,有两个函数,子函数访问了父函数中的变量,就形成了闭包。下面是一个闭包的例子。


function father() {
    var familyName = "wang"; // 父函数的变量
    function child() { 
        return familyName + ' hong';
    }
    child(); // 执行子函数,访问父函数的变量,形成闭包
}
father();

常规来说,函数体中的局部变量都是私有的,只在该函数体内可以被访问到,但是child函数却可以访问到father函数中的familyName变量。因为child函数在执行时形成了闭包,延长了作用域链,child的作用域链包含了father的作用域。这种行为可被称作"链式作用域"结构,子对象会逐一向上寻找所有父对象的变量,因此child函数可以取到father函数中的变量的值。

闭包有什么用?

1、拥有私有变量和私有方法,避免造成变量污染


(function(){
    var myName = 'wang hong';
    var getName = function () {
        console.log(myName); // 'wang hong'
    };
    window.getName = getName; // 指向window,可全局访问该变量
})();

这是一个自执行函数,同时也是闭包。在这个闭包中的变量和方法,是该自执行函数所私有的,不可被外部访问,也不会与外部变量发生重名冲突。如果想要让自执行函数内的变量或者方法被外部所访问,可将其指向window或者使用return。这其实跟Module十分相似,或者可以理解为Module就是闭包。

2、让变量始终保持在内存中

闭包的特性,使变量始终不被回收,因此可以用来存一些需要缓存的数据。下面是一个缓存的例子


function setCache(fn) {
  var cache = {}; // 始终保存在内存中的对象
  return function() {
    var key =  Array.prototype.join.call(arguments,',');
    cache[key] = cache[key] || fn.apply(this, arguments);
    return cache[key];
  }
}

var setVal = setCache(function(val) { 
    console.log(val); // 执行两次setVal(2)时,此处只执行1次 
    return val;
});
setVal(2);
setVal(2);
setVal(3);

cache是闭包中的变量,始终不被销毁。以上代码执行了两次setVal(2),cache对象会使用缓存中的值,不会再一次执行fn方法。当setVal传入不同于之前的参数时,fn方法会向cache对象中添加新的值。

闭包的缺陷

由于闭包的特性,闭包中的变量始终会被保存在内存中,不被垃圾回收机制回收,因此会消耗内存,影响整体性能。

上一篇下一篇

猜你喜欢

热点阅读