如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
如何向某人解释JavaScript关闭,知道它们所构成的概念(例如功能、变量等),但不了解关闭本身?
我已经在维基百科上看到了图表的例子,但不幸的是,它没有帮助。
当前回答
我倾向于通过好/坏的比较更好地学习,我喜欢看到工作代码跟随不工作的代码,有人可能会遇到,我把一个 jsFiddle 组合起来,它进行比较,并试图将差异推向我能找到的最简单的解释。
关闭是正确的:
console.log('CLOSURES DONE RIGHT');
var arr = [];
function createClosure(n) {
return function () {
return 'n = ' + n;
}
}
for (var index = 0; index < 10; index++) {
arr[index] = createClosure(index);
}
for (var index of arr) {
console.log(arr[index]());
}
关闭错误:
console.log('CLOSURES DONE WRONG');
function createClosureArray() {
var badArr = [];
for (var index = 0; index < 10; index++) {
badArr[index] = function () {
return 'n = ' + index;
};
}
return badArr;
}
var badArr = createClosureArray();
for (var index of badArr) {
console.log(badArr[index]());
}
在上面的代码中,路径在创建ClosureArray()函数中移动,函数现在只会返回完成的路径,这在第一眼看起来更直观。
结果
其他回答
考虑到这个问题是关于简单地解释它,就像一个6岁的,我的答案是:
“当您在JavaScript中宣布函数时,它将永久地访问在该函数声明之前线上可用的所有变量和函数,该函数和它所访问的所有外部变量和函数都是我们称之为关闭的。
一个关闭是内部函数在其外部函数中有变量的访问,这可能是最简单的单线解释,你可以获得关闭。
函数 foo(x) { var tmp = 3;函数栏(y) { console.log(x + y + (++tmp)); // 会记录 16 } 栏(10); } foo(2);
函数栏,以及其与函数 foo 的语法环境的联系,是关闭。
函数 foo(x) { var tmp = 3; 返回函数 (y) { console.log(x + y + (++tmp)); // 还会记录 16 } } var bar = foo(2); bar(10); // 16 bar(10); // 17
一个关闭的最简单的例子是:
var a = 10; 函数测试() { console.log(a); // 将输出 10 console.log(b); // 将输出 6 } var b = 6; 测试();
我思考关闭的越多,我会看到它作为一个2步过程: init - 行动
init: pass first what's needed...
action: in order to achieve something for later execution.
到6岁时,我会强调关闭的实际方面:
Daddy: Listen. Could you bring mum some milk (2).
Tom: No problem.
Daddy: Take a look at the map that Daddy has just made: mum is there and daddy is here.
Daddy: But get ready first. And bring the map with you (1), it may come in handy
Daddy: Then off you go (3). Ok?
Tom: A piece of cake!
例如:把一些牛奶带到妈妈(=行动)。首先做好准备,然后把地图(=init)带到这里。
function getReady(map) {
var cleverBoy = 'I examine the ' + map;
return function(what, who) {
return 'I bring ' + what + ' to ' + who + 'because + ' cleverBoy; //I can access the map
}
}
var offYouGo = getReady('daddy-map');
offYouGo('milk', 'mum');
因为如果你带着一个非常重要的信息(地图),你有足够的知识来执行其他类似的操作:
offYouGo('potatoes', 'great mum');
对于一个开发人员来说,我会在关闭和OOP之间进行平行。 init 阶段类似于在传统 OO 语言中向构建者传达论点; 行动阶段最终是你呼吁实现你想要的方法。
请参见我的另一个答案,描述OO和关闭之间的平行性:
如何在JavaScript中“正确”创建自定义对象?
我写了一篇博客帖子一段时间后解释关闭,这里是我在关闭方面所说的,为什么你会想要一个。
关闭是让一个函数有持久的,私人变量的方式 - 也就是说,只有一个函数知道的变量,在那里它可以跟踪从以前运行的时间的信息。
在这个意义上,他们让一个函数有点像一个具有私人属性的对象。
完整帖子:
那么,这些关闭事物是什么呢?