比较两个数字自面量如(1===1) 或者布尔型字面量(true===false)是有意义的
但是==运算符和===运算符无法用来比较对象,这是因为他们是按引用而不是按值进行比较的。
浅复制对象的属性比较算法:这是一种非递归的浅复制算法,换句话说,我们只比较附属于对象的第一类属性,冰壁比较属性的属性,在大多情况下这样做就可以了。
// 比较对象,如果所有属性都相等,则返回true
function objcmp(a,b){
// 将属性复制到A和B中
let A=Object.keys(a);
let B=Object.keys(b);
// 如果属性个数不相等,则提前返回
if(A.length!=B.length){
return false;
}
// 遍历并比较两个对象的所有属性
for(let i=0;i<A.length;i++){
let propName=A[i];
// 属性的值和烈性必须相等
if(a[propName]!==b[propName]){
return false
}
}
// 对象相等
return true
}
let one={
name:'hello',
level:6
}
let two={
level:6,
name:'hello'
}
let result=objcmp(one,two);
console.log(result); //true
不过这里存在一个大问题,在目前形式下,该函数的属性不可以指向数组和对象,这两种常见的数据结构很可能就是某个对象的一部分。即使不进行深度比较。只要某个属性指向对象或数组,不管两个对象的属性个数和实际值是否相同,函数也都会返回false如以下
let one={
obj:{},
prop:[1,2],
name:'Misaka Mikoto',
level:6
}
let two={
obj:{},
prop:[1,2],
level:6,
name:'Misaka Mikoto'
}
let result=objcmp(one,two); //false
此时需要单独处理一下数组
if (!Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === '[object Array]';
};
}
比较两个对象是否相等:注意:此代码只对普通对象、数组、函数、日期和基本类型的数据结构进行对比
function isDeepEqual(obj1, obj2, testPrototypes = false) {
if (obj1 === obj2) {
return true
}
if (typeof obj1 === 'function' && typeof obj2 === 'function') {
return obj1.toString() === obj2.toString()
}
if (obj1 instanceof Date && obj2 instanceof Date) {
return obj1.getTime() === obj2.getTime()
}
if (Object.prototype.toString.call(obj1) !== Object.prototype.toString.call(obj2) && typeof obj1 !== 'object') {
return false
}
const newB = testPrototypes ? isDeepEqual(Object.getPrototypeOf(obj1), Object.getPrototypeOf(obj2), true) : true
const obj1Props = Object.getOwnPropertyNames(obj1)
const obj2Props = Object.getOwnPropertyNames(obj2)
return (
obj1Props.length === obj2Props.length && newB && obj1Props.every(item => isDeepEqual(obj1[item], obj2[item]))
)
}
// let a={
// prop:[1,2],
// obj:{}
// }
// let b={
// prop:[1,2],
// obj:{}
// }
let a='123';
let b=123;
const result=isDeepEqual(a,b)
console.log(result)