JS深拷贝

什么是深拷贝?

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

而深拷贝则是开辟新的栈,两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。深拷贝指的是对象属性所引用的对象全部进行新建对象拷贝,以保证深拷贝的对象的引用图不包含任何原有对象或对象图上的任何对象,隔离出两个完全不同的对象图。

深拷贝的两种常用方法:

一. json方法

var targetObj = JSON.parse(JSON.stringify(Obj))

let targetArr = JSON.parse(JSON.stringify(arr))

原理:用JSON.stringify将对象转成JSON字符串,再用JSON.parse()把字符串解析成对象,对象会开辟新的栈,实现深拷贝

缺点

  1. 会抛弃对象的constructor,也就是深拷贝之后,无论这个对象原本的构造函数是什么,在深拷贝之后都会变成Object。即,无法拷贝copyObj对象原型链上的属性和方法
  2. RegExp对象是无法通过这种方式深拷贝的,同样function函数也无法转成JSON被拷贝下来

二. 递归方法

function deepClone( source ) {
    //如果不是对象的话直接返回
    if (typeof source !== 'object' || source == null){
        return source; 
    }
    //判断是对象还是数组,初始化
    let target = Array.isArray( source ) ? [] : {} 
    
    for ( var k in source ) {
    	if (source.hasOwnProperty(k)) {    //保证k不是原型上的属性
            if ( typeof source[ k ] === 'object' ) {
            	target[ k ] = deepClone( source[ k ] )    //递归
            } else {
            	target[ k ] = source[ k ]
            }
    	}
    }
    return target
}
复制代码

原理: 在浅拷贝部分的原理是一样的,如果第一层键名/下标 对应的是基础类型的值,就直接赋值,如果是引用类型的值,采用递归的方式,进入到这个引用类型的值。到了第二层,循环操作第一层的步骤。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享