function isObjectEquals(obj1,obj2){
//如果引用的是同一个对象,则直接返回true
if(obj1 === obj2) return true
//若不是对象类型或者是null
if(typeof obj1 !== 'object' || typeof obj1 === null || typeof obj2 !== 'object' || typeof obj2 === null){
return false
}
const visited = new Map() //防止递归遍历时,对象存在自身引用的情况
//let obj4 = {}
//obj.self = obj4
const stack = [{obj1,obj2}] //显示栈,替换掉递归调用,避免递归深度过大,出现栈溢出
// debugger
while(stack.length){
const {obj1,obj2} = stack.pop()
if(obj1 === obj2){
continue
}
if(typeof obj1 !== 'object' || typeof obj1 === null || typeof obj2 !== 'object' || typeof obj2 === null){
return false
}
if(visited.has(obj1)){
if(visited.get(obj1) !== obj2) return false
continue
}
visited.set(obj1,obj2) //存储对象对
const keys1 = Reflect.ownKeys(obj1)
const keys2 = Reflect.ownKeys(obj2)
if(keys1.length !== keys2.length){
return false
}
for(let key of keys1){
if(!keys2.includes(key)) return false
const val1 = obj1[key]
const val2 = obj2[key]
//如果值是函数
if(typeof val1 === 'function' || typeof val2 === 'function'){
if(val1.toString() !== val2.toString()){
return false
}
}else if(typeof val1 === 'object' && typeof val1 !== null && typeof val2 === 'object' && typeof val2 !== null){
stack.push({obj1:val1,obj2:val2})
}else if(val1 !== val2){
return false
}
}
}
return true
}
let obj1 = {
name:'aDong',
age:20,
hobbies:["篮球","编程","Vue"],
methods: {
type:1,
get:()=>{},
set:{
a:[7,8,9],
b:5
}
},
getAge:function(){return this.age}
}
let obj2 = {
name:'aDong',
age:20,
hobbies:["篮球","编程","Vue"],
methods: {
type:1,
get:()=>{},
set:{
a:[7,8,9],
b:5
}
},
getAge:function(){return this.age}
}
console.log(isObjectEquals(obj1,obj2));//true
console.log(Object.is(obj1,obj2));//false
console.log(NaN === NaN);//false
console.log(Object.is(NaN,NaN));//true
Object.is()是js内置的一个api,但是和===基本上没有区别,只是对一些特殊情况做出了特殊处理,所以并不能用来比较两个对象是否相等。所以必须得手写一个判断对象是否相等的方法