React中React.PureComponent和React.memo的浅比较
/**
*
* @param {props || state} objA
* @param {nextProps || nextState} objB
*/
var address = [10, 20]
var a = {
name: 'jack',
age: 25,
address: address
}
var b = {
name: 'jack',
age: 25,
address: address
}
//认为上述两个对象是相同的
var c = {
name: 'jack',
age: 25,
address: [10, 20]
}
var d = {
name: 'jack',
age: 25,
address: [10, 20]
}
//认为上述两个对象是不相同的,因为address的引用不同
//两个对象相同指的是:两个对象的属性个数相同且两个对象的属性相同,并且两个对象的属性值也一样,属性值一样 //指的是引用一样,不再深度比较这两个对象里面的东西是否一样了,这就是浅比较。
function shallowEqual(objA, objB) {
if (Object.is(objA, objB)) { //react中Object.is做了polyfill
return true //这边可以比较出两个基本数据类型,且两个对象引用相同则认为是true。
}
//只要有一个不是对象数据类型,则返回false,不用再进行比较了
if (typeof objA !== 'object' || typeof objB !== 'object'
|| typeof objA === 'null' || typeof objB === 'null'
) {
return false
}
//这里就可以判断出obja,objb都是对象数据类型了,再去判断两者是否相同。
var objAkeys = Object.keys(objA)
var objBKeys = Object.keys(objB)
if (objAkeys.length !== objBKeys.length) {
return false
}
//只要两者有属性不相同,或者属性的值不相同(即引用不同),则认为两者不相等。
for (let i = 0; i < objAkeys.length; i++) {
if (!objB.hasOwnProperty(objAkeys[i]) || !Object.is(objA[objAkeys[i]], objB[objBKeys[i]])) {
return false
}
}
return true //走到这一步,说明两个对象的属性一样,且属性值也一样
}
// 实际上是Object.is()的polyfill
function is(x, y) {
// SameValue algorithm
if (x === y) {
// 处理为+0 != -0的情况
return x !== 0 || 1 / x === 1 / y;
} else {
// 处理 NaN === NaN的情况
return x !== x && y !== y;
}
};
console.log(shallowEqual(a, b)) //true
console.log(shallowEqual(c, d)) //false
//深度比较
function deepEqual(objA, objB) {
if (Object.is(objA, objB)) {
return true //这边可以比较出两个基本数据类型,且两个对象引用相同则认为是true。
}
//只要有一个不是对象数据类型,则返回false,不用再进行比较了
if (typeof objA !== 'object' || typeof objB !== 'object'
|| typeof objA === 'null' || typeof objB === 'null'
) {
return false
}
//这里就可以判断出obja,objb都是对象数据类型了,再去判断两者是否相同。
var objAkeys = Object.keys(objA)
var objBKeys = Object.keys(objB)
if (objAkeys.length !== objBKeys.length) {
return false
}
//只要两者有属性不相同,或者属性的值不相同(即引用不同),则认为两者不相等。
for (let i = 0; i < objAkeys.length; i++) {
if (!objB.hasOwnProperty(objAkeys[i]) || !Object.is(objA[objAkeys[i]], objB[objAkeys[i]])) {
return false
} else {
if (!deepEqual(objA[objAkeys[i]], objB[objAkeys[i]])) {
return false
}
}
}
return true //走到这一步,说明两个对象的属性一样,且属性值也一样
}
console.log(deepEqual(a, b)) //true
console.log(deepEqual(c, d)) //true