愈来愈以为国内没有教书育人的气氛,为了弄懂JS的闭包,我使出了我英语四级吃奶的劲去google上征采着有封闭包的诠释,当我看到stackoverflow上这一篇解答,我脑中就涌现了一句话:就是这货没跑了!
鄙人译文见下,见笑了。
Peter Mortensen问:
就像老Albert所说的,“假如你不能向一个六岁的孩子诠释清晰,那末实在你自身基础就没弄懂。”好吧,我试着向一个27岁的朋侪就是JS闭包(JavaScript closure)却完全失利了。
你们会怎样把它诠释给一个充溢好奇心的六岁孩子听呢?
注:我看过StackOverflow上给出的示例,但基础没用。
Ali的回复:
当function里嵌套function时,内部的function能够接见外部function里的变量。
function foo(x) {
var tmp = 3;
function bar(y) {
alert(x + y + (++tmp));
}
bar(10);
}
foo(2)
不论实行多少次,都邑alert 16,因为bar能接见foo的参数x,也能接见foo的变量tmp。
但,这还不是闭包。当你return的是内部function时,就是一个闭包。内部function会close-over外部function的变量直到内部function完毕。
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar 如今是一个闭包
bar(10);
上面的剧本终究也会alert 16,因为虽然bar不直接处于foo的内部作用域,但bar照样能接见x和tmp。
然则,因为tmp仍存在于bar闭包的内部,所以它照样会自加1,而且你每次挪用bar时它都邑自加1.
(考虑到六岁这个限定:我们实在能够竖立不止一个闭包要领,比方return它们的数组,也能够把它们设置为全局变量。它们全都指向雷同的x和雷同的tmp,而不是各自有一份副本。)
注:如今来整点儿七岁的内容。
上面的x是一个字面值(值通报),和JS里其他的字面值一样,当挪用foo时,实参x的值被复制了一份,复制的那一份作为了foo的参数x。
那末题目来了,JS里处置惩罚object时是用到援用通报的,那末,你挪用foo时通报一个object,foo函数return的闭包也会援用最初谁人object!
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}
var age = new Number(2);
var bar = foo(age); // bar 如今是一个援用了age的闭包
bar(10);
不出我们预料,每次运转bar(10),x.memb都邑自加1。但须要注重的是x每次都指向同一个object变量——age,运转两次bar(10)后,age.memb会变成2.
这和HTML对象的内存走漏有关,呃,不过貌似超出了答题的局限。
JohnMerlino 对Ali说:
这里有一个不必return关键字的闭包例子:
function closureExample(objID, text, timedelay) {
setTimeout(function() {
document.getElementById(objID).innerHTML = text;
}, timedelay);
}
closureExample(‘myDiv’, ‘Closure is created’, 500);
深夜1:37 John Pick如许回复:
JS里的function能接见它们的:
1. 参数
2. 部分变量或函数
3. 外部变量(环境变量?),包含
3.1 全局变量,包含DOM。
3.2 外部函数的变量或函数。
假如一个函数接见了它的外部变量,那末它就是一个闭包。
注重,外部函数不是必须的。经由过程接见外部变量,一个闭包能够保持(keep alive)这些变量。在内部函数和外部函数的例子中,外部函数能够建立部分变量,而且终究退出;然则,假如任何一个或多个内部函数在它退出后却没有退出,那末内部函数就保持了外部函数的部分数据。
一个典范的例子就是全局变量的运用。
mykhal如许回复:
Wikipedia对闭包的定义是如许的:
In computer science, a closure is a function together with a referencing environment for the nonlocal names (free variables) of that function.
从技术上来说,在JS中,每一个function都是闭包,因为它老是能接见在它外部定义的数据。
Since scope-defining construction in Javascript is a function, not a code block like in many other languages, what we usually mean by closure in Javascript is a fuction working with nonlocal variables defined in already executed surrounding function.
闭包常常用于建立含有隐蔽数据的函数(但并不老是如许)。
var db = (function() {
// 建立一个隐蔽的object, 这个object持有一些数据
// 从外部是不能接见这个object的
var data = {};
// 建立一个函数, 这个函数供应一些接见data的数据的要领
return function(key, val) {
if (val === undefined) { return data[key] } // get
else { return data[key] = val } // set
}
// 我们能够挪用这个匿名要领
// 返回这个内部函数,它是一个闭包
})();
db('x'); // 返回 undefined
db('x', 1); // 设置data['x']为1
db('x'); // 返回 1
// 我们不可能接见data这个object自身
// 然则我们能够设置它的成员
看了这么多外国大牛的解答,不晓得你懂照样不懂,横竖我是懂了。
P.S. 宣布文章以后看到@xiaotie的一篇文章,以为有必要引荐一下,因为其理会得更加深切。有人说应该在文章末端对闭包举行总结,惋惜小弟才疏学浅,不能给出一个精炼的总结。
@xiaotie对闭包的总结以下:
(1)闭包是一种设想准绳,它经由过程剖析上下文,来简化用户的挪用,让用户在不晓得的情况下,到达他的目标;
(2)网上主流的对闭包理会的文章实际上是和闭包准绳反向而驰的,假如须要晓得闭包细节才用好的话,这个闭包是设想失利的;
(3)只管少进修。
原文地点:
http://kb.cnblogs.com/page/11…