数组浅拷贝
1.原始循环放入新数组
2.arr.slice() 返回新数组
3.arr.concat() 返回新数组
4.[...arr] 扩展运算符
以上方法只能浅拷贝一维数组、(含对象的数组只能拷贝到对象的引用地址)
对象浅拷贝
浅拷贝之所以被称为浅拷贝,是因为对象只会被克隆最外部的一层,至于更深层的对象,则依然是通过引用指向同一块堆内存.
[...obj] 扩展运算符 浅拷贝
Object.assign 是浅拷贝
var a={
obj:{a:'name'}
}
var c=Object.assign({},a)
c.obj.a='name111';
console.log(a) //{"obj":{"a":"name111"}}
深拷贝 数组、对象值包含引用类型值的时候
JSON.parse( JSON.stringify());
这种简单粗暴的方法有其局限性。当值为undefined、function、symbol 会在转换过程中被忽略。。。所以,对象值有这三种的话用这种方法会导致属性丢失。
存在的坑:
1.他无法实现对函数 、RegExp等特殊对象的克隆
2.会抛弃对象的constructor,所有的构造函数会指向Object
3.对象有循环引用,会报错
var arr = ['old', 1, true, ['a1', 'a2'], {num: 1}]
var new_arr = JSON.parse( JSON.stringify(arr) );
手写数组和对象 拷贝
浅拷贝
var shallowCopy = function(obj) {
// 只拷贝对象
if (typeof obj !== 'object') return obj;
// 根据obj的类型判断是新建一个数组还是对象
var newObj = obj instanceof Array ? [] : {};
// 遍历obj,并且判断是obj的属性才拷贝
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
newObj[key] = obj[key];
}
}
return newObj;
}
深拷贝方法
尽管使用深拷贝会完全的克隆一个新对象,不会产生副作用,但是深拷贝因为使用递归,性能会不如浅拷贝,在开发中,还是要根据实际情况进行选择。
function deepCopy(obj) {
if (typeof obj == "object") {
//复杂数据类型
var result= Array.isArray(obj) ? [] : {};
for (let i in obj) {
result[i] = typeof obj[i] == "object" ? deepCopy(obj[i]) : obj[i];
}
return result;
} else {
//简单数据类型 直接赋值
return obj;
}
}