js中的深拷贝和浅拷贝的扩展

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

react对于虚拟dom的比较是render的前提,开发者可以自定义scu实现渲染优化。然而scu的对象层次比较多,比较会比较耗时。有时候深层次的比较时间反而高于render时间。那么如何优化scu中的比较就是个问题。弄清楚这个之前我们需要知道js的引用类型和基本类型以及深拷贝和浅拷贝是怎么回事。

1,对于字符串类型,浅复制是对值的复制,对于对象来说,浅复制是对对象地址的复制,并没 有开辟新的栈,也就是复制的结果是两个对象指向同一个地址,修改其中一个对象的属性,则另一个对象的属性也会改变,而深复制则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。

 

深复制实现代码如下:
可以从两个方法进行解决。
第一种方法、通过递归解析解决

18125552_hMzl.jpg

 var china = {nation : '中国',birthplaces:['北京','上海','广州'],skincolr :'yellow',friends:['sk','ls']}//深复制,要想达到深复制就需要用递归function deepCopy(o,c){var c = c || {}for(var i in o){if(typeof o[i] === 'object'){//要考虑深复制问题了if(o[i].constructor === Array){//这是数组c[i] =[]}else{//这是对象c[i] = {}}deepCopy(o[i],c[i])}else{c[i] = o[i]}}return c}var result = {name:'result'}result = deepCopy(china,result)console.dir(result)

第二种方法:通过JSON解析解决

 var test ={name:{xing:{ first:'张',second:'李'},ming:'老头'},age :40,friend :['隔壁老王','宋经纪','同事']}var result = JSON.parse(JSON.stringify(test))result.age = 30result.name.xing.first = '往'result.friend.push('fdagldf;ghad')console.dir(test)console.dir(result)

浅复制代码大概如下:

var obj = {a: 1,arr: [ 2, 3 ]};
var shadowObj = shadowCopy( obj );
function shadowCopy( src ) {var dst = {};for ( var prop in src ) {if (src.hasOwnProperty( prop )) {dst[prop] = src[prop];}}return dst;}

 

因为浅复制只会将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shadowObj.arr 指向同一块内存地址,大概的示意图如下。

18125552_bxfC.png

 

 

综上所述,对象的深复制特别需要递归遍历属性复制,当属性嵌套比较深,性能会很差。

 

对象的比较也是同样的道理。 react 官方给的解决方案是immutable.js  利用对象的不可变性。 每次修改对象的时候,都会返回一个全新的对象,因此可以直接通过=== 判断对象是否相等,从而优化render,那每次生成全新的对象会不会影响性能?请继续往下看。

Immutable Data 就是一旦创建,就不能再被更改的数据。对 Immutable 对象的任何修改或添加删除操作都会返回一个新的 Immutable 对象。Immutable 实现的原理是 Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保证旧数据同时可用且不变。同时为了避免 deepCopy 把所有节点都复制一遍带来的性能损耗,Immutable 使用了 Structural Sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。请看下面动画:

Immutable 原理动画

 

也就说每次对immutable对象修改虽然会生成一个不同的对象,但是数据结构是共享的,因此避免了刚才深拷贝带来的性能问题。 一方面提高了性能,另一方面相对于浅拷贝,解决了层级大于一层无法比较的问题

据说这种做法可以显著提高react性能

转载于:https://my.oschina.net/wanjubang/blog/903505


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部