2011-12-22 62 views
2

我有一個功能,複製包含鍵:函數對, 包含每個函數調用函數的地圖。Javascript範圍和hashmaps

function duplicateFunctionsMap(functionsMap){ 

    var newMap = {}; 

    for (var name in functionsMap){ 

     var originalFunc = functionsMap[name]; 

     newMap[name] = function(){ 
      originalFunc(); 
     } 
    } 

    return newMap; 
} 

現在試圖在複製地圖運行任何條目原來總是調用最後一個

duplicateFunctionsMap({ 
         first: function(){alert("first");}, 
         last: function(){alert("last");} 
         })["first"](); // outputs "last" 

回答

3

你必須引入一個範圍,以防止originalFunc更改。功能引入一個新的範圍,但for循環不:

for (var name in functionsMap){ 
    (function(originalFunc) { 
     newMap[name] = function(){ 
      originalFunc(); 
     }; // <-- add semicolon at end of expression, too 
    })(functionsMap[name]); 
} 
0

裏面你的週期,你可能已經創建了一個閉合。試試這個代碼,創建一個匿名內立即執行功能

for (var name in functionsMap){ 
    (function(_of) { 
     newMap[name] = _of; 
    }(functionsMap[name])) 
} 

參見javascript closure immediate evaluation

+0

在這種情況下,匿名函數是矯枉過正,因爲直接設置工作過。 – pimvdb 2011-12-22 14:56:32

+0

這不會重複功能 – Esailija 2011-12-22 16:54:13

2

有這個900萬次的重複,但在這裏不用.. JavaScript的 沒有一個塊級範圍。重複這一點。

所以就變成:

function duplicateFunctionsMap(functionsMap) { 

    var newMap = {}; 

    for (var name in functionsMap) { 
     var originalFunc = functionsMap[name]; 

     newMap[name] = (function (originalFunc) { 
      return function() { 
      originalFunc(); 
      }; 
     })(originalFunc); 

    } 

    return newMap; 
} 

請注意,如果您想複製使用情況下,參數的函數和返回值,你需要這樣做:

newMap[name] = (function (originalFunc) { 
    return function() { 
     return originalFunc.apply(this, arguments); 
    }; 
})(originalFunc); 

否則,你的複製功能失去一切那些好東西。