2012-02-17 38 views
8

this answer有一個簡單的函數,它將返回包含原始值的數組的數組相等性。爲什麼或如何證明JavaScript數組相等?

但是,我不確定它爲什麼有效。這裏是功能:

function arrays_equal(a,b) { return !!a && !!b && !(a<b || b<a); } 

我最感興趣的是下半場;該位:

!(a<b || b<a) 

爲什麼比較<>工作時,陣列但==不?

JavaScript中的小於和大於方法是如何工作的?

回答

10

隨着</>,數組首先轉換爲字符串,因此不提供檢查相等的可靠方法。

==,因爲對象是通過引用檢查不起作用:

[] == []; // false, two separate objects 

var a = []; 
a == a; // true, refer to the same object 

</>招是有缺陷的:

var a = [1, [2, 3]], 
    b = [[1, 2], 3]; 

!(a<b || b<a); // true 

這個計算結果爲true,因爲它們都轉換成字符串"1,2,3"檢查前(</>不「直接」爲對象工作)。

所以基本上,你是比較字符串的平等。對於字符串,a == b確實與!(a<b || b<a)-</>相同,因爲字符串檢查字符代碼,所以兩個相等的字符串既不是「小」也不是「更大」,因爲對於字符串中的任何字符代碼情況並非如此。

+0

+1獲得一些新的每一天JS。可愛的語言 – Sarfraz 2012-02-17 19:37:20

+0

@Sarfraz:是的,直到你經歷了一些令人討厭的調試之後才發現像這樣的事情... – pimvdb 2012-02-17 19:40:04

+0

最近開始學習它**認真**,前進:)。你應該有一個博客的方式:) – Sarfraz 2012-02-17 19:41:08

4

您可以使用==比較任意兩個對象。但是因爲>和<沒有爲對象定義,所以它們被轉換爲字符串。因此,[1,2,3]>[2,1,3]實際上是"1,2,3">"2,1,3"

+1

這是不正確的。轉換並不總是以字符串。 [11.8.5](http://es5.github.com/#x11.8.5)指定對象轉換髮生在類型提示'「number」'so'arrays_equal(new Date(1),1)''爲true '。 – 2012-02-17 20:13:05

+0

謝謝;並請Mike在他的評論中予以澄清! – 2012-02-17 20:26:32

5

但是,我不確定它爲什麼起作用。

它不起作用。考慮

arrays_equal(["1,2"], [1,2]) 

即使通過任何基於元素明智比較的數組相等的定義也會產生true,它們是不同的。

arrays_equal([[]], []) 

arrays_equal([""], []) 

也是假陽性。

簡單地增加length檢查並不會有助於

arrays_equal(["1,2",3], [1,"2,3"]) 

arrays_equal(
    ["",","], 
    [",",""]) 

編輯所證實:

如果你想有一個簡潔的方式來測試結構相似性,我建議:

function structurallyEquivalent(a, b) { 
    return JSON.stringify(a) === JSON.stringify(b); 
} 

它並不會在明顯不同的輸入上提前停止 - 它會遍歷這兩個對象圖,而不管它們是多麼不相似,但函數OP。

警告:當你使用非母語JSON.stringify,它可以做奇怪的事情循環輸入,比如:

var input = []; 
input[0] = input; 
+1

即使對於原語,「JSON.stringify」可能不完全可靠。考慮'[,]'和'[null]'。 – pimvdb 2012-02-17 20:06:40

+0

@ pimvdb,當然。它將'null'和'undefined'/elipsis混合起來,但JavaScript ==也是如此。 OP中沒有任何內容表示對'==='優先於'=='。 – 2012-02-17 20:07:43

+0

謝謝,你的回答和@ pimvdb一起進一步幫助我理解。 – 2012-02-17 20:25:47

相關問題