闭包
Q:是什么?
- A:
- 够读取其他函数内部变量的函数,是将函数内部和函数外部连接起来的一座桥梁。——by:阮一峰
- 词法表示包括不被计算的变量的函数。——by:W3school
- 函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。——by:MDN
Q:能干什么?
-
A:
-
可以从内部函数访问外部函数的作用域,允许将函数与其 所操作的某些数据(环境)关联起来。
//示例
function makeAdder(x) {
return function (y) {
return x + y;
};
}
//此时传入makeAdder中的x
var add5 = makeAdder(5);
var add10 = makeAdder(10);
//此时传入makeAdder中的y,但是函数会记住之前传的x
console.log(add5(2)); // 7
console.log(add10(2)); // 12 -
模拟私有方法,闭包可以访问私有函数和变量。
var Counter = (function () {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function () {
changeBy(1);
},
decrement: function () {
changeBy(-1);
},
value: function () {
return privateCounter;
},
};
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */ -
让变量的值始终保持在内存中。
-
Q:什么时候被创建?
- A:随着函数的创建而被同时创建。
Q:闭包的缺点是什么?
- A:在处理速度和内存消耗方面对脚本性能具有负面影响
Q:如何避免闭包?
-
A:
-
将异步获取值保留到新增的闭包中
//存在闭包
for(var i = 0;i < 10;i++){
setTimeout(()=>{console.log(i),1000})
}
//优化
function init3() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
//嵌套多一层闭包
(function(arg){
pAry[i].onclick = function() {
alert(arg);
};
})(i);//调用时参数
} -
将变量值保留到作用域之外
-