2011-10-10 127 views
5

以下是Firebug的完成:在Javascript中,爲什麼[1,2] == [1,2]或({a:1})==({a:1})爲false?

>>> [1, 2] == [1, 2] 
false 

>>> ({a : 1}) == ({a : 1}) 
false 

我想Javscript有一些規定說,如果一個對象或數組具有相同的元素相同的標記,那麼他們是平等的嗎?

但是即使我說

>>> foo = {a : 1} 
Object { a=1} 

>>> [foo] == [foo] 
false 

>>> ({a: foo}) == ({a: foo}) 
false 

有沒有辦法讓這個它可以做的元素的比較,並返回true

+12

對象文字創建新實例,定義兩個實例不會讓它們共享相同的引用。 – zzzzBov

+0

它不是「內部元素」,需要相等嗎? –

回答

6

{ }[ ]是相同的new Objectnew Array

而且new Object != new Object(同上同Array),因爲它們新的和不同對象。

如果你想知道兩個arbitary對象的內容是否是「相同」因爲那時的相同的一些值快速(但慢)的修復

JSON.parse(o) === JSON.parse(o)

一個更優雅的解決方案將是定義一個等於函數(未測試的)

var equal = function _equal(a, b) { 
    // if `===` or `==` pass then short-circuit 
    if (a === b || a == b) { 
    return true; 
    } 
    // get own properties and prototypes 
    var protoA = Object.getPrototypeOf(a), 
     protoB = Object.getPrototypeOf(b), 
     keysA = Object.keys(a), 
     keysB = Object.keys(b); 

    // if protos not same or number of properties not same then false 
    if (keysA.length !== keysB.length || protoA !== protoB) { 
    return false; 
    } 
    // recurse equal check on all values for properties of objects 
    return keysA.every(function (key) { 
    return _equal(a[key], b[key]); 
    }); 
}; 

equals example

警告:編寫一個在所有輸入上「工作」的相等函數是很難的,一些常見的陷阱是(null == undefined) === true(NaN === NaN) === false,這兩個函數在我的函數中都沒有提到。

我也沒有處理任何跨瀏覽器問題,我只是假設ES5存在。

+0

'!=='!=='!=';-) –

+0

你有很多補丁與該功能。例如。 'equal({},{})=== false'。另外,我認爲你的意思是用'_equal'遞歸。 – davin

+0

@davin'_equal'只是一個約定,我不知道如何優雅地處理'{}'和'[]'。這也問到「equals(Object.create(foo),Object.create(bar))'是否應該爲true或false。 – Raynos

0

它是因爲JavaScript對象文字不共享相同的指針。相反,每個人都會創建一個新的指針。請看下面的例子:

>>> ({a : 1}) == ({a : 1}) 
false 

...但是...

>>> obj = ({a : 1}); 
Object 

>>> obj == obj 
true 

obj是一個指向litteral對象{ a : 1 }。所以這是有效的,因爲當你比較它們時指針是一樣的

0

你正在比較不同的對象。

>>> var a = [1,2] var b = [1,2] 
>>> a == b 
false 
>>> a == a 
true 

如果你想測試數組的相等性,你可能想使用一些庫或者只是自己寫測試。

相關問題