闭包是指有权访问另一个函数作用域中变量的函数。创建闭包的最常见的方式就是在一个函数A内创建另一个函数B,通过函数B访问函数A的局部变量。(js高级教程)
1 闭包的作用(优点)
1)读取另一个函数作用域中的变量;
2)让这些变量始终保持在内存中,即闭包可以使得它诞生环境一直存在。
3)封装对象的私有属性和私有方法。(然后在全局作用域中通过调用闭包就能访问函数中的变量)
2 闭包的缺点(坏处)
由于闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存,过度使用闭包可能会导致内存占用过多的问题。
所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
闭包的应用—循环中使用闭包解决 var 定义函数的问题
/*变量i是var命令声明的,在全局范围内都有效,所以全局只有一个变量i。
每一次循环,变量i的值都会发生改变,而循环内setTimeout的回调函数中使用console.log(i),
里面的i指向的就是全局的i。
*/
for( var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000);
} //输出5个6
//因为 setTimeout 是个异步函数,所有会先把循环全部执行完毕,这时候 i 就是 6 了,所以会输出一堆 6。
解决方法
1)使用闭
for (var i = 1; i <= 5; i++) {
(function(j) {
setTimeout(function timer() {
console.log(j);
}, j * 1000);
})(i);
} //1 2 3 4 5(每行一个数字)
2)使用 setTimeout 的第三个参数
for ( var i=1; i<=5; i++) {
setTimeout( function timer(j) {
console.log( j );
}, i*1000, i);
}
3)使用let
for ( let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
this对象是在运行时基于函数的执行环境绑定的。
每一个函数在调用时都会自动取得两个特殊的变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此永远不可能直接访问外部函数中的这两个变量。不过,如果把外部作用域中的this和arguments对象保存在一个闭包能够访问的变量里面,就可以在闭包中访问者两个对象了。其应用可以看防抖节流、apply等手写实现。
在下面的例子中对象obj中方法getName中定义了一个闭包。使用obj.getName(18)调用闭包的外部函数,其getName中的this和arguments指向obj和 [Arguments] { '0': 18 }。在全局中调用闭包,在非严格模式下的浏览器中,其this指向全局对象window。
var name = "outer";
var obj = {
name: "inner",
getName: function (age) { //闭包
console.log(this, arguments); // { name: 'inner', getName: [Function: getName] } [Arguments] { '0': 18 }
return function () {
return {
th: this,
age: age,
na: name,
arg: arguments
}
}
}
}
var func = obj.getName(18); //获得闭包, getName中的this和arguments指向obj和 [Arguments] { '0': 18 }
var result = func(12, "多余的参数"); //执行闭包 闭包中的this和arguments指向undefined(浏览器为window)和 [Arguments] { '0': 12, '1': '多余的参数' } }
console.log(result);
/*console.log(obj.getName(18)(12, "多余的参数"));*/ //这句和上面三句执行结果一样
/*node环境下的返回值
{ th:Object [global] {...} //注意这里,谷歌浏览器返回的是window对象
age: 18,
na: undefined, //谷歌浏览器是outer
arg: [Arguments] { '0': 12, '1': '多余的参数' } }*/
1)node环境下返回值截图(上)
中间一堆node全局环境。。
2)浏览器返回值截图
1 循环中使用闭包解决 var
定义函数的问题(答案:其应用里面就是)
2
百里于2020年7月20日
如果有错,请您指出!如有侵权,请联系我删除!