对象拷贝的四种方法以及利弊分析

1 使用JSON.parse(JSON.stringify(obj))

会返回原对象的副本,可以进行深拷贝

let newObj = JSON.parse(JSON.stringify(obj));

注意:

当原对象中某个属性值为函数时,会将此属性丢失,拷贝后的对象中没有此属性,因此该方法不可以拷贝用户自定义的方法属性;
同时, 不能用于复制循环引用对象,如以下报错.


image.png

2 使用ES6中的 Object.assign()

Object.assign() 方法用于将从一个或多个源对象中的所有可枚举的属性值复制到目标对象(即参数中的第一个对象),并返回合并后的对象.
可以复制循环引用对象

let objCopy = Object.assign({}, obj);

注意:

Object.assign 只是浅拷贝,只能复制第一层属性;

3 使用ES6中的展开操作符(…)

const array = ["a","c","d", {four: 4},];
const newArray = [...array];

注意:只对浅拷贝有效

4 使用递归进行深拷贝

function copy (obj) {
    var newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== 'object') return;   
    for(var i in obj){
        newobj[i] = typeof obj[i] === 'object' ? copy(obj[i]) : obj[i];
    }
    return newobj
}
var copyArray = copy(array)

注意不适用于循环引用对象,对于循环引用对象,可以使用插件将循环解开.

********************************************************************

总结:

(1 )JSON.parse(JSON.stringify(obj))适用于深拷贝属性中没有值为方法的对象,适用于非循环引用的对象;

(2) Object.assign()适用于浅拷贝对象,循环或者非循环都可以;

(3) 递归深拷贝适用于非循环引用的对象.

********************************************************************

附加:关于数组的拷贝,修改后对原数组无影响

var array = [1, 2, 3, 4];
var newArray = array.slice();
var array = [1, 2, 3, 4];
var newArray = array.concat();

你可能感兴趣的:(对象拷贝的四种方法以及利弊分析)