2011-09-20 44 views
5

JavaScript對象基於值還是基於引用?例如:javascript中的值類型引用類型對象

obj1.list =new array(); 
// ------ populate list 
obj2.list = obj1.list 

是否瀏覽器進行obj1.list的不同副本obj2.list,或者是obj2.list只是obj1.list參考?

+2

它是基於參考的。 – BoltClock

+1

[Javascript的等號參考對象或克隆它們是否可能的重複](http://stackoverflow.com/questions/7467335/does-javascript-equal-sign-reference-objects-or-clones-them) – RobG

回答

14

JavaScript對象(通過擴展:陣列,正則表達式,日期,非原始字符串/數字/布爾值等等)平等和分配是基於參考:

{a:'a'} == {a:'a'} // false 

但:

var myObject = {a:'a'}; 
var myObject2 = myObject; 

myObject == myObject2 // true 

此外:

myObject.b = 'b'; 

console.log(myObject2.b); // Logs: "b" 
+0

這是沒錯,但並沒有真正解決上述問題。這種比較是錯誤的,因爲它們中的每一個都是獨立的對象,並且對象的相等性比較以查看它們是否在內存中是完全相同的對象 - 它不查看對象的內容。 – jfriend00

+0

@ jfriend00 - 我不明白你在說什麼。我已經清楚地解釋說,評估*和*作業都是基於參考的。 –

+0

我在閱讀您的文章時只看到前兩行。我不確定你是否編輯了你的答案以增加更多內容,或者因爲沒有向我展示所有內容。您目前的答案更完整。 – jfriend00

2

分配使得警察只有當它是一個原始類型(如Number,Boolean等)時,該值纔是值。否則,賦值只是將引用複製到同一個對象(Object,Array等)。一個新的對象不是通過賦值來創建的。

所以,在你的榜樣:

obj1.list =new array(); 
// ------ populate list 
obj2.list = obj1.list 

obj2.push("foo"); 
alert(obj1.pop); // "foo" (they are both the same list) 

obj1.listobj2.list將指向同一個對象(包含同一對象的引用)

3

JavaScript是基於引用語義:

var a = [1,2,3]; 
var b = a; 
a[0] = 42; 
alert(b[0]); // will show 42 
var c = a.slice(); // explicitly makes a copy 
a[1] = 6502; 
alert(c[1]); // will show 2, not 6502 
4

忘記所有關於「引用」的低級別廢話(,這些不存在於JavaScript中),並考慮下面列出的簡單規則。術語「對象」用於表示特定的值,其不一定是「對象」;這並沒有改變規則,而是強化了一致性。

1)一個對象本身。如果對象可變,並且該對象發生了突變,那麼該對象已發生突變

2)賦值不是創建對象的副本/克隆/副本。這包括爲函數調用中的參數「賦值」的值。 對象的值。

3)的變量(或屬性)不是一個對象,而它是一個名稱一個對象(一個相當的方式來表達「變量的計算結果爲給定的對象」)。 A 單個對象可以有許多「名稱」,但它是相同的對象

其他一切都是實現細節 - 參考文獻中沒有提到在所有的規範中都提到過。而應注意的是,原始值(例如numberstring不能爲分配了其他屬性(分配將被忽略),而包裝對象NumberString是完整的對象。這與上面的規則是一致的:JavaScript中沒有可變的非對象值。爲了討論JavaScript語言,可以將基元值視爲對象,儘管它們是完全不可變的,並且不是對象。

快樂編碼。