2013-03-31 79 views
-1

我有以下的javascript代碼:JavaScript對象項目名稱

var oReg = new Object; 
oReg.a = {size: 762, content: 0}; 
oReg.b = {size: 342, content: 0}; 
//... 

for (var s in oReg) { 
    oReg[s].set = function(i) { 
     alert('#name of oReg item#: ' + i); 
    } 
} 

在哪裏「的俄勒岡項##NAME」應該是A,B等
我認爲它應該被this開始,但我不能想出來。

+0

而你的問題是..? – Daedalus

+0

而不是「oReg項#的#name」應該是「s」,但是你不能寫「s」,因爲變量不存在於函數本身中,只在循環中 – andrew

+0

@andrew該變量確實存在於循環外部,但是當'set'被調用時它總是指向最後一個鍵。 – bfavaretto

回答

3

它應該是s而不是i,但不幸的是它不是那麼簡單,因爲「infamous loop problem」。您必須在每次迭代中創建一個新的作用域(函數創建作用域),以便能夠保留每個值s的引用。否則,您的setter將始終返回最後一個對象鍵的值。

下面的代碼應該這樣做:

for (var s in oReg) { 
    oReg[s].set = (function(key) { 
     return function() { 
      alert('#name of oReg item#: ' + key); 
     } 
    }(s)); 
} 
+0

非常感謝,解決問題 – andrew

+0

@andrew:不要忘記您點擊旁邊的複選標記以接受此問題。 –

0

我知道很多人會開始哭泣看到在代碼中eval一個電話,但扔用戶輸入到它時,真的只有危險。因此:

var oReg = new Object; 
oReg.a = {size: 762, content: 0}; 
oReg.b = {size: 342, content: 0}; 

for (var s in oReg) { 
    eval("oReg[s].set = function(i){alert('oReg."+s+": ' + i);}"); 
} 
+1

*「在將用戶輸入引入它時真的很危險」* ...您是對的,但還有其他一些避免「eval」的原因:編譯器運行速度慢,編譯器難以優化,代碼難以維護。 –

+0

接受的評論,我想我今天再學到一些東西:)取而代之的是bfavaretto的回答。 – tomsmeding

0
var oReg = new Object; 
oReg.a = {size: 762, content: 0}; 
oReg.b = {size: 342, content: 0}; 
//... 

for (var s in oReg) { 
    oReg[s].set = (function(s) { 
     alert('#name of oReg item#: ' + s); 
    })(s); 
} 

我想你想做到這一點。

+0

這將在每次迭代時發出警報,並且對於每個密鑰,「set」都是未定義的。 – bfavaretto