2012-04-05 2 views
0

Dies ist eine Art seltsames Problem. Angesichts des unten stehenden Javascript erwarte ich, dass das newFunctions-Objekt Funktionen enthält, die ein Originalobjekt umschließen, es führt jedoch nur die letzte Aktion aus, die in der Schleife vorkommt. Sollte nicht var actionToCall einen Verweis darauf kopieren, was currentAction gerade betrachtet, und nicht ändern, wenn die Schleifen iterieren? Ich bin hier ratlos.Javascript-Objekt erstellt von objectsss immer Referenzen letzten Element

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

Antwort

1

Dies liegt daran, dass actionToCall currentAction zugewiesen wird.

Da currentAction global ist, ändert sich sein Wert ständig, während die Schleife iteriert.

Wenn die Schleife endet, wird currentAction evenMore zugewiesen.

Hier ist der Fix mit einer Self-Execution-Funktion, um Umfang zu induzieren.

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