这是一种奇怪的问题。鉴于下面的javascript,我期望newFunctions对象包含包装原始对象的函数,但是它只运行循环中发生的最后一个操作。 var actionToCall不应该复制对currentAction当前正在查看的内容的引用,而不是在循环迭代时更改吗?我在这里难过。
var typeArray = {
type1: {
function1: function() {
console.log("this is function 1");
},
function2: function() {
console.log("this is function 2");
}
},
type2: {
somefunction: function() {
console.log("this is some function")
}
},
type3: {
blah: function() {
return;
},
moreBlah: function(something) {
console.log(something);
},
evenMore: function() {
console.log("I'm last!");
}
}
},
index,
typeIndex,
currentType,
actionIndex,
currentAction,
newFunctions = {};
for(typeIndex in typeArray) {
currentType = typeArray[typeIndex];
for(actionIndex in currentType) {
currentAction = currentType[actionIndex];
console.log(currentAction.toString());
newFunctions[actionIndex] = function() {
var actionToCall = currentAction;
console.log("about to run action");
actionToCall.call(this);
console.log("action has been called");
}
}
}
console.log(newFunctions);
for(index in newFunctions) {
(newFunctions[index])();
}
答案 0 :(得分:1)
这是因为actionToCall被分配给currentAction。
由于currentAction是全局的,因此当循环迭代时,它的值会不断变化。
当循环结束时,currentAction被分配给evenMore。
这是使用自我执行功能来引导范围的修复。
var typeArray = {
type1: {
function1: function() {
console.log("this is function 1");
},
function2: function() {
console.log("this is function 2");
}
},
type2: {
somefunction: function() {
console.log("this is some function")
}
},
type3: {
blah: function() {
return;
},
moreBlah: function(something) {
console.log(something);
},
evenMore: function() {
console.log("I'm last!");
}
}
},
index,
typeIndex,
currentType,
actionIndex,
currentAction,
newFunctions = {};
for(typeIndex in typeArray) {
currentType = typeArray[typeIndex];
for(actionIndex in currentType) {
currentAction = currentType[actionIndex];
console.log(currentAction.toString());
//induce scope here so actionToCall keeps the current value of currentAction.
(function(){
var actionToCall = currentAction;
newFunctions[actionIndex] = function() {
console.log("about to run action");
actionToCall.call(this);
console.log("action has been called");
}
})();
}
}
console.log(newFunctions);
for(index in newFunctions) {
(newFunctions[index])();
}