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

本文探讨了React中的shouldComponentUpdate(SCU)优化策略及其存在的问题,并介绍了使用Immutable.js进行状态管理来提高React应用性能的方法。文章还详细解释了深拷贝与浅拷贝的区别,以及Immutable.js如何通过结构共享机制提升效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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 = 30
	  result.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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值