javascript是不能用 '=='或'==='操作符直接比較兩個(gè)數(shù)組是否相等的
var a = [1,2,3,4,5];
var b = a.slice();
console.log(a); // [1,2,3,4,5]
console.log(b); // [1,2,3,4,5]
console.log(a === b); // false
console.log(a == b); // false
console.log([] == []); // false
console.log( [] === []); // false
為什么都輸出false呢?先弄清楚以下幾點(diǎn):
javascript包括兩個(gè)不同類型的值:基本數(shù)據(jù)類型和引用數(shù)據(jù)類型。
基本數(shù)據(jù)類型指的是簡(jiǎn)單的數(shù)據(jù)段,引用數(shù)據(jù)類型指的是有多個(gè)值構(gòu)成的對(duì)象。
常見的基本數(shù)據(jù)類型:Number、String 、Boolean、Null和Undefined。
var a = 10;
var b = a;
b = 20;
console.log(a); // 10
上面b獲取的是a值的一份拷貝,雖然兩個(gè)變量的值相等,但是兩個(gè)變量保存了兩個(gè)不同的基本數(shù)據(jù)類型值。b只是保存了a賦值的一個(gè)副本,所以,b的改變,對(duì)a沒有影響。
引用類型數(shù)據(jù):也就是對(duì)象類型Object type,比如:Object、Array、Function、Data等。javascript的引用數(shù)據(jù)類型是保存在堆內(nèi)存中的對(duì)象。
講到這里應(yīng)該理解為什么輸出的是false了:因?yàn)閿?shù)組是兌現(xiàn),==或===操作符只能比較兩個(gè)對(duì)象是否是同一個(gè)實(shí)例,也就是是否是同一個(gè)對(duì)象引用。目前JavaScript沒有內(nèi)置的操作符判斷對(duì)象的內(nèi)容是否相同。
那么該如何去判斷數(shù)組是否相等呢?
有一種做法是將數(shù)組轉(zhuǎn)換成字符串:
JSON.stringify(a1) === JSON.stringify(a2)
或
a1.toString() === a2.toString();
請(qǐng)不要使用這種方法?。?!
這種方法在某些情況下是可行的,當(dāng)兩個(gè)數(shù)組的元素順序相同且元素都可以轉(zhuǎn)換成字符串的情況下確實(shí)可行。
這樣的代碼存有隱患,比如數(shù)字被轉(zhuǎn)換成字符串,數(shù)字“1”和字符串“1”會(huì)被認(rèn)為相等,可能造成調(diào)試?yán)щy,不推薦使用。
function isEqual (a, b) {
const classNameA = toString.call(a)
const classNameB = toString.call(b)
// 如果數(shù)據(jù)類型不相等,則返回false
if (classNameA !== classNameB) {
return false
} else {
// 如果數(shù)據(jù)類型相等,再根據(jù)不同數(shù)據(jù)類型分別判斷
if (classNameA === '[object Object]') {
for (let key in a) {
if (!isEqual(a[key], b[key])) return false
}
for (let key in b) {
if (!isEqual(a[key], b[key])) return false
}
return true
} else if (classNameA === '[object Array]') {
if (a.length !== b.length) {
return false
} else {
for (let i = 0, len = a.length; i < len; i++) {
if (!isEqual(a[i], b[i])) return false
}
return true
}
} else if (classNameA === '[object Function]') {
return a.toString() === b.toString()
} else {
return Object.is(a, b)
}
}
}
const a = {
arr: [1, true, {a: 6, arr: [9, 0, 6, [5, 9]]}],
d: 0,
obj: { d: 9, arr: [5000]},
e: ()=>{},
f: [0]
}
const b = {
arr: [1, true, {a: 6, arr: [9, 0, 6, [5, 9]]}],
d: 0,
obj: { d: 9, arr: [5000]},
e: ()=>{},
f: [0]
}
console.log(isEqual(a, b))