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 複製代碼