闭包的概念:
- 在一个函数内有权访问另一个函数内部的变量
- 在一个函数内部创建另一个函数
- 闭包内的变量不会清空 会造成内存泄漏
闭包的使用场景:
-
返回值
function fn() { var [a,b] = [1,2]; function getData(){ return a+b } return getData; } var fnc = fn() console.log(fnc());// 3
-
函数赋值
var fn2; function fn(){ var name = 'zxzxzxzx'; 将函数赋值给fn2 fn2 = function (){ return name; } } fn();// 要先执行进行赋值 console.log(fn2());// zxzxzxzx
-
函数参数
function fn(){ var name = 'zxzxzxzx'; return function getData(){ return name; } } var fnc = fn();// 执行函数将返回值赋值给 getData function fnb(ff){ // 将函数作为参数传入 console.log(ff());;// 执行函数,并输出 } fnb(fnc)
用闭包返回一个函数,把fnc函数作为另一个函数的参数,在另一个函数里面执行这个函数
-
自执行函数
(function (){ var name = 'zxszxz'; var fn1 = function (){ return name } // 直接在自执行函数里面调用fn2 将fn1作为参数传入 fn2(fn1) })() function fn2(ff){ // 将函数作为参数传入 console.log(ff()); // 执行函数 }
直接在自执行函数里面将封装的函数fn1传给fn2,作为参数调用同样可以获得结果 zxszxz
-
循环赋值
for (let i = 0; i <=5; i++) { (function(j){ setTimeout(function(){ console.log(j);// 0 1 2 3 4 5 依次打印出 }, j*1000); })(i) }
闭包的好处:
- 保护函数内的变量安全,实现封装,防止变量流入其他环境 发生命名冲突
- 在内存中维持一个变量,可以做缓存(使用多了会消耗)
- 匿名自执行函数可以减少内存消耗
闭包的坏处:
- 被引用的私有变量不能被销毁,增大内存消耗,造成内存泄漏,解决方法是在使用完变量后手动为他赋值为null
- 由于闭包涉及跨域访问,所以会导致性能损失。解决方法是 可以把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响。