我有这个示例代码:
function(){
var events = [];
var pages = ["a", "b", "c"];
for(var pageIndex in pages){
var pageName = pages[pageIndex];
var e = function(){
console.info(pageName);
};
events.push(e);
}
for(var eventIndex in events){
console.info("index: " + eventIndex);
events[eventIndex]();
}
}
输出:
index: 0
c
index: 1
c
index: 2
c
期望的输出:
index: 0
a
index: 1
b
index: 2
c
这是否有标准做法?
答案 0 :(得分:1)
欢迎使用javascript中的闭包,你需要将函数包装在IIFE中或立即调用函数表达式,这将创建一个闭包并将状态保存在其范围内:
(function(){
var events = [];
var pages = ["a", "b", "c"];
for(var pageIndex in pages){
var pageName = pages[pageIndex];
var e = (function(pageName){
return function() {console.info(pageName);};
}(pageName));
events.push(e);
}
for(var eventIndex in events){
console.info("index: " + eventIndex);
events[eventIndex]();
}
}());
将其复制并粘贴到控制台调试器中以进行测试......
答案 1 :(得分:1)
您创建的每个e
函数都是一个闭包,它从封闭代码中访问外部变量pageName
。它将看到的pageName
是函数运行时的值 。因此,在循环结束时pageName
为"c"
,这就是所有函数在执行时将使用的内容。
您可以通过以下方式包装函数来解决此问题,这将基本上将pageName
的当前值绑定到您创建的函数:
function(){
var events = [];
var pages = ["a", "b", "c"];
for(var pageIndex in pages){
var pageName = pages[pageIndex];
var e = (function(data) {
return function() {
console.info(data);
};
})(pageName);
events.push(e);
}
for(var eventIndex in events){
console.info("index: " + eventIndex);
events[eventIndex]();
}
}
答案 2 :(得分:0)
我找到了答案here。我需要将我的函数包装在另一个函数中。真漂亮。
Template.index.test = function(){
var events = [];
var pages = ["a", "b", "c"];
for(var pageIndex in pages){
var pageName = pages[pageIndex];
var e = function(pageName) {
return function(){
console.info(pageName);
};
}(pageName);
events.push(e);
}
for(var eventIndex in events){
console.info("index: " + eventIndex);
events[eventIndex]();
}
}