内容简介:在React里,shouldComponentUpdate源码为:可以看到PureComponent就是对props跟state的前后状态做了一个浅比较。看看shallowEqual的源码:
在React里,shouldComponentUpdate源码为:
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps) || !shallowEqual(inst.state, nextState);
}
复制代码
可以看到PureComponent就是对props跟state的前后状态做了一个浅比较。
看看shallowEqual的源码:
const hasOwn = Object.prototype.hasOwnPropertyfunctionis(x, y) {
if(x === y) {
returnx !==0 || y !==0 ||1/ x ===1/ y
} else {
returnx !== x && y !== y
}
}
export default function shallowEqual (objA, objB) {
if ( is(objA, objB ))
return true
i f( typeofobjA !=='object' || objA === null || typeofobjB !=='object' || objB ===null) {
return false
}
const keysA = Object.keys ( objA )
const keysB = Object.keys ( objB )
if ( keysA.length !== keysB.length)
return false
for ( leti =0; i < keysA.length; i++) {
if ( !hasOwn.call ( objB, keysA[i] ) || !is(objA[keysA[i]], objB[keysA[i]])) {
return false
}
}
return true
}
复制代码
Object.is ()
在解析 shallowEqual
的源码之前,先来认识一下 Object.is()
,这个函数是用来比较两个值是否相等。
为什么要用这个来比较而不是 ==
或者 ===
呢?
==
首先先看 ==
,由于 JS 是弱类型的,如果使用 ==
进行比较, ==
操作符会自动将 0,‘’(空字符串),null,undefined
转成布尔型 false
,这样就会出现
0==' '// true null==undefined// true [1] ==true// true 复制代码
这显然是不符合预期的。所以 JS 为我们提供了全等操作符 ===
,它不会进行类型转换,也就是说如果两个值一样,必须符合类型也一样。但是,它还是有两种疏漏的情况
+0 === -0//true,但我们期待它返回falseNaN===NaN//false,我们期待它返回true 复制代码
所以, Object.is()
修复了 `=== 这两种判断不符合预期的情况,
function (x, y){
// SameValue algorithm
if(x === y) {
// 处理为+0 != -0的情况
returnx !==0 || 1/ x ===1/ y;
} else {
// 处理 NaN === NaN的情况
return x !== x && y !== y;
}
};
复制代码
这样就使得 Object.is()
总是返回我们需要的结果。 它在下面6种情况下,会返回 true
-
两个值都是
undefined -
两个值都是
null -
两个值都是
true或者都是false - 两个值是由相同个数的字符按照相同的顺序组成的字符串
- 两个值指向同一个对象
-
两个值都是数字并且
+0 -0
-
都是
NaN -
都是除零和
NaN外的其它同一个数字
可以看出 Object.is
可以对基本数据类型: null,undefined,number,string,boolean
做出非常精确的比较,但是对于引用数据类型是没办法直接比较的。
剖析 shallowEquall
// 用原型链的方法
const hasOwn = Object.prototype.hasOwnProperty
// 这个函数实际上是 Object.is() 的 polyfill
functionis (x, y) {
if (x === y) {
returnx !==0 || y !==0 ||1/ x === 1/ y
} else {
returnx !== x && y !== y
}
}
export default function shallowEqual (objA, objB) {
// 首先对基本数据类型的比较
if (is(objA, objB))
return true
// 由于 Obejct.is() 可以对基本数据类型做一个精确的比较, 所以如果不等
// 只有一种情况是误判的,那就是 object, 所以在判断两个对象都不是 object
// 之后,就可以返回 false 了
if (typeofobjA !== 'object' || objA === null || typeofobjB !== 'object' || objB ===null ) {
return false
}
// 过滤掉基本数据类型之后,就是对对象的比较了
// 首先拿出 key 值,对 key 的长度进行对比
const keysA = Object.keys( objA)
const keysB = Object.keys(objB)
// 长度不等直接返回 false
if (keysA.length !== keysB.length)
return false
// key 相等的情况下,在去循环比较
for (let i =0; i < keysA.length; i++) {
// key值相等的时候
// 借用原型链上真正的 hasOwnProperty 方法,判断ObjB里面是否有A的key的key值
// 属性的顺序不影响结果也就是 {name:'daisy', age:'24'} 跟 {age:'24',name:'daisy' } 是一样的
// 最后,对对象的value进行一个基本数据类型的比较,返回结果
if( !hasOwn.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])){
return false
}
}
return true
}
复制代码
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- React 函数式组件性能优化指南
- 一个鲜为人知的高性能组件注册及实现组件排序技巧
- Cookbook:优化 Vue 组件的运行时性能
- Cookbook:优化 Vue 组件的运行时性能
- (译)Istio 组件的性能与伸缩性
- [译] 用 Web Worker 改善 Vue 组件性能
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
正则表达式必知必会(修订版)
福达 (Ben Forta) / 杨涛 / 人民邮电出版社 / 2015-1-1 / 29.00元
《正则表达式必知必会》从简单的文本匹配开始,循序渐进地介绍了很多复杂内容,其中包括回溯引用、条件性求值和前后查找,等等。每章都为读者准备了许多简明又实用的示例,有助于全面、系统、快速掌握正则表达式,并运用它们去解决实际问题。正则表达式是一种威力无比强大的武器,几乎在所有的程序设计语言里和计算机平台上都可以用它来完成各种复杂的文本处理工作。而且书中的内容在保持语言和平台中立的同时,还兼顾了各种平台之......一起来看看 《正则表达式必知必会(修订版)》 这本书的介绍吧!