0

这是一个奇怪的问题。鉴于下面的 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])();
  }
4

1 回答 1

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])();
}
于 2012-04-05T18:24:36.617 回答