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 に答える