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对象中添加新的值。
闭包的缺陷
由于闭包的特性,闭包中的变量始终会被保存在内存中,不被垃圾回收机制回收,因此会消耗内存,影响整体性能。