2012-05-17 192 views
2

看下面的代碼,有人可以解釋如何在JavaScript中傳遞值。JavaScript變量賦值?

function loadImages() { 
    for(var sec in images) { 
    theme = images[sec]; 
     for(var tsec in theme) { 
     theme[tsec].img = new Image(); 
     theme[tsec].img.src = 'images/'+theme[tsec].src+'.png'; 
     } 
    } 
} 

然後在另一個功能:

function definitionToSpriteDataMapping() { 
    var result = {}; 
    for(var definition in blocks) { 
    var sprite = blocks[definition].sprite; 
    for(var secnm in images) { 
     section = images[secnm]; 
     for(var spritenm in section) { 
     if(sprite == spritenm) { 
      result[definition] = {}; 
      result[definition].img = section.img; 
     } 
     } 
    } 
    } 
    return result; 
} 

我剪了一些代碼爲簡單起見,但它仍然相當令人費解。基本上有兩個對象(圖片&塊),它們是嵌套的鍵:值對。在的代碼

theme = images[sec]; 
theme[tsec].img.src = 'images/'+theme[tsec].src+'.png'; 

第一塊中的第二行代碼有

section = images[secnm]; 
result[definition] = {}; 
result[definition].img = section.img; 

中有「圖像」不.IMG的代碼的第一個塊,其中加入的.img之前「主題」。但是這似乎反映回第二塊代碼所見的「圖像」。所有對象都像JavaScript中的指針嗎? 「結果」與「主題」與「圖像」具有相同的「塊」關係嗎?如果我從「主題」中刪除元素,會在「圖像」中反映出來怎麼辦?

+0

如果它寫成'i = new Image(); i.img.src ='images /'+ theme [tsec] .src +'。png';主題[tsec] = i;'它會對你更有意義嗎? –

回答

4

使用theme = images[sec]你確實將創建一個指向內存中的對象。因此,將img添加到theme對象中並將img添加到該圖像,因爲它們是相同的對象。所以是的,result也是如此。
以這種方式更改,添加或刪除引用的對象的屬性將影響實際的對象。數組也是一樣。

如果你不喜歡這種行爲,你應該克隆該對象。你可以簡單地通過複製所有屬性克隆一個簡單的對象:

var original = { name: "James", age: 73, male: true }; 
var clone = { }; 
for(var k in original) 
    clone[ k ] = original[ k ]; 

但如果original的任何財產是一個數組或對象本身,這將是一個參考。如果你沒有任何對象或數組作爲屬性,上面的代碼片段將會很好。否則,您應該編寫一個克隆函數並遞歸克隆原始的每個成員。

2

是否所有對象都像JavaScript中的指針?

實際上,是的,儘管我相信會更普遍地聲明在JavaScript中對象是「引用類型」。

如果var a引用的對象,a被分配到var bb將獲得參考的副本a成立,所以ab都將在內存中引用同一個對象的數據。

a參考引起的更改可從b參考中觀察到。

請注意,這仍然是一個「按值」分配,但複製的值是引用的值,而不是對象本身。

1

你在改變images[sec][tsec]在這兩種情況下,這是指內存中的同一個對象。只是做theme = images[sec]不會複製該對象。

的這種行爲更簡單的例子是這樣的:

var obj = {}; 
var obj2 = obj; 

obj.a = 123; 
obj2.a; // 123