React中PureComponent和memo的浅比较

React中React.PureComponent和React.memo的浅比较react

/**
 * 
 * @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的引用不一样bash

//两个对象相同指的是:两个对象的属性个数相同且两个对象的属性相同,而且两个对象的属性值也同样,属性值同样 //指的是引用同样,再也不深度比较这两个对象里面的东西是否同样了,这就是浅比较。markdown

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
复制代码
相关文章
相关标签/搜索