javascript 闭包和作用域链示例
-
21-12-2019 - |
题
有人可以(清楚、简洁地)向我解释为什么这段代码会这样工作吗?我来自 Java(6 和 7)的强类型背景,其中不存在闭包,也不像 javascript 那样发挥作用。我认为与这个问题相关的概念是:闭包和作用域链。
这是例子:
var myfuncs = function() {
var funcs = []
var i;
for (i = 0; i < 10; i++) {
funcs[i] = function() { console.log(i); }
}
return funcs;
}
var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); });
上面的示例记录了 9(10 次),但预期和我自己的直觉认为它会记录 0-9。
为什么它会像 JavaScript 中那样工作?闭包非常强大,但我正在努力一劳永逸地掌握这个概念!稍微修改一下示例就会产生正确的输出,但为什么呢?
var myfuncs = function() {
var funcs = []
var i;
for (i = 0; i < 10; i++) {
funcs[i] = (function(index) { console.log(index); })(i);
}
return funcs;
}
var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); });
闭包并不是 Javascript 所独有的,但我想了解为什么它们在 javascript 实际编写为与浏览器/dom 交互的上下文中如此强大。
有没有人有好的、实用的例子来说明我们如何在与浏览器/dom 交互时应用闭包技术?
谢谢。
解决方案
在你的例子中,它非常简单。
在你的第一个例子中,只有一个变量 i
并且所有内容都引用该单一值。所以..它打印数字 9
十次。每个函数捕获一个 共享 的价值 i
这会改变。
在第二个示例中,您使用的是闭包。每个函数都有一个私有变量,称为 index
它接收——这是重要的部分—— 复制 的价值 i
.
所以,你得到 0
通过 9
因为有十个函数,每个函数都有一个私有的 index
变量和每一个 index
变量获取快照 i
因为它当时存在。
这种较长形式的闭包可能会有所帮助:
function myFactory(index) {
return function() {
console.log(index);
}
}
var myfuncs = function() {
var funcs = []
var i;
for (i = 0; i < 10; i++) {
funcs[i] = myFactory(i);
}
return funcs;
}
var allfuncs = myfuncs();
allfuncs.forEach(function(fn) { fn(); });
不隶属于 StackOverflow