从对象创建的 Javascript 对象总是引用最后一个元素

Javascript object created from objectss always references last element

本文关键字:对象 引用 最后一个 元素 Javascript 创建      更新时间:2023-09-26
这是一个

奇怪的问题。鉴于下面的 javascript,我希望 newFunctions 对象包含包装原始对象的函数,但它只运行循环中发生的最后一个操作。var actionToCall 不应该复制对当前操作当前正在查看的内容的引用,并且在循环迭代时不更改吗?我在这里被难住了。

  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])();
  }

这是因为 actionToCall 被分配给了当前操作。

由于 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])();
}