闭包是什么
- 闭包是一个函数
- 闭包能访问函数内部的变量
- 创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,
- 利用闭包可以突破作用链域,将函数内部的变量和方法传递到外部。
闭包的特性:
- 函数内再嵌套函数
- 内部函数可以引用外层的参数和变量
- 参数和变量不会被垃圾回收机制回收
闭包的作用
有两大作用:
- 访问函数内部的变量
- 将变量保存在内存中,不会使变量在函数销毁后变量自动清除
为啥说不会使变量在函数执行完以后销毁了
function f1(){
var a = 342;
// 这就是一个闭包函数
return function (){
console.log(a)
}
}
f1()(); // 342
原因就是这个闭包函数成了一个全局函数,始终在内存中,而这个闭包函数是依赖f1函数存在的,所以说f1也始终在内存中,不会在掉用完之后被垃圾回收机制回收了。
如果是一个函数里边的变量,在函数执行完之后,就会被回收了。
如果是全局变量,会一直在内存中(因为系统不知道啥时候还能再用到这个全局变量),不会被回收。
闭包在开发中的作用
在实际开发中,闭包主要用于封装变量,收敛权限。
比如,我们判断一个数组中是否存在某个元素,不存在就返回不存在且将这个元素存进去;存在就返回存在。
我们在做这个例子时,希望不能随便修改list这个数组,只是传入某个元素,以此来判断。
function check(){
var list = []
return function(item){
if(list.indexOf(item) > -1){
console.log("存在")
}else{
console.log("不存在")
list.push(item)
}
}
}
var c1 = check();
c1("aaa") // 不存在
c1("aaa") // 存在
c1("bbb") // 不存在
这里,如果外界想访问list数组,只能通过check函数访问,
我对想访问list的外界只提供了check()这一个接口。至于怎么操作list,我已经定义好了,外界能做的就只是使用我的函数,然后传几个不同的参数罢了。
几个示例:
function outer(){
let num = 0;
return function add(){
num++;
console.log(num)
}
}
let f1 = outer()
f1()
f1()
let f2 = outer()
f2()
f2()
// 1 2 1 2
let scope = "global scope";
function checkScope (){
let scope = "local scope";
function f(){
return scope;
}
return f
}
console.log(checkScope()()); // local scope
let scope = "global scope";
function checkScope (){
let scope = "local scope";
return scope
}
console.log(checkScope()) // local scope
过度使用闭包的危害
很多高级应用都要靠闭包来实现
但是,闭包是把函数中的变量保存在内存中了,内存消耗很大,如果滥用闭包会造成页面性能问题
,在IE中会造成内存泄露。
解决方法
:在退出函数之前,将不再使用的局部变量删除掉
闭包会在父函数外部,改变父函数内部变量的值。
所以把父函数当做对象使用,把闭包当做它的公共方法,把内部变量当成私有属性时,不要随便修改父函数内部变量的值。
网友评论