React Native 性能优化组件-PureComponent

栏目: IOS · Android · 发布时间: 7年前

内容简介:在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
}
复制代码

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Functional Programming in Scala

Functional Programming in Scala

Paul Chiusano、Rúnar Bjarnason / Softbound print / 2014-9-14 / USD 44.99

Functional programming (FP) is a programming style emphasizing functions that return consistent and predictable results regardless of a program's state. As a result, functional code is easier to test ......一起来看看 《Functional Programming in Scala》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具