2012-04-05 32 views
0

這是一種奇怪的問題。鑑於下面的javascript,我期待newFunctions對象包含包裝原始對象的函數,但它只運行循環中發生的最後一個操作。 var actionToCall不應該將引用複製到currentAction當前正在查看的內容,並且在循環迭代時不會更改?我被困在這裏。從objectss創建的Javascript對象始終引用最後一個元素

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

回答

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])(); 
} 
相關問題