古老定义
闭包(closure )是指函数变量可以保存在函数范围内,因此函数看起来“包裹”了变量。//根据定义,包含变量的函数为闭包
函数foo
var a=0;
}
cosole.log(a ) )。
//uncaughtreferenceerror 3360 Aisnotdefined
《JavaScript高级程序设计》对闭包定义
闭包是指可以访问另一个函数范围内的变量的函数根据《JavaScript高级程序设计》,访问上位函数的作用域的内层函数为闭包
函数foo
var a=2;
功能栏
控制台日志(a;
}
bar (;
}
foo (;
《JavaScript权威指南》对闭包定义
函数对象可以通过范围链相互关联,函数主体内部的变量可以保存在函数范围内。 这就是闭包。var全局='全局范围'; //全局变量
功能检查范围
var scope='本地scope '; //局部变量
函数f ()
返回范围; 用//范围返回这个值
(;
返回f (;
}
检查范围(;//返回到本地范围
严格来说,闭包必须满足三个条件。 【1】访问所在范围【2】嵌入函数【3】在所在范围外调用
因为有人认为只满足条件1就可以了,所以有人认为IIFE只有满足闭包的条件1和2才可以,所以也有人认为只有嵌套函数闭包的三个条件都满足了才可以,所以在作用域以外的地方调用的函数才是闭包
为什么我们需要闭包
首先让我们来看一个例子。 实现计数器吧。var计数器=0;
函数添加
返回计数器=1;
}
add (;
add (;
add (; //计数器现在为3
现在我们达到了目的,但是发生了问题。 该计数器并不完美,因为代码中的任何函数都可以自由改变counter的值。 那么,把counter放入add函数中不就行了吗?
函数添加
var计数器=0;
返回计数器=1;
}
add (;
add (;
add (; //本意是想输出3,但输出的都是1
这样,每次调用add函数时,counter的值都会初始化为0,仍然无法实现我们的目的。
如何使用闭包
所以这个时候闭包解决这个问题。 请先看代码。瓦德=(函数) )。
var计数器=0;
返回函数() {返回计数器=1; }
() )
add (;
add (;
add (; //计数器为3
这个时候我们完美地实现了计数器。 该段非常紧凑,可以划分为等效代码,如下所示。
功能外部功能
var计数器=0;
功能内部功能
返回计数器=1;
}
返回内部功能;
}
var add=外部功能(;
add (;
add (;
add (; //计数器为3
这时的add形成了闭包。 闭包由函数和创建该函数的环境两部分组成。 由环境中的局部变量构成。 对于闭包add,由于由函数innerFunction和变量counter组成,因此此时add可以访问变量counter。
使用闭包应注意的问题
由于闭包承载包含它的函数的范围,所以比其他函数消耗更多的内存。 因此,可以手动取消对匿名函数的引用以释放内存。函数F2 () {
var n=22;
var nadd=函数() ) n;
返回函数(
返回
n:n,
与:与
}
}
}
//result2是创建匿名函数
var result2=f2(;
调用//函数
控制台日志(结果2 ) );
结果2 () .与);
控制台日志(结果2 ) );
//取消对匿名函数的引用,释放内存
结果2=空值;
译文: https://段故障.com/a/119000015980718