array 拷贝第一层
- slice或者concat,这两个方法都能返回一个新的数组而不影响原来的数组
var a1=["1","2"]; var a2=a1.slice(0); a2.push("2"); console.log(a1,a2)//[1,2] [1,2,2]
- 扩展运算符 ...
对象中的扩展运算符(...)用于取出参数对象中的所有可遍历属性,拷贝到当前对象之中
var a1=["1","2"];
var a2=[...a1];
a2.push("2");
console.log(a1,a2);
3.Object.assign Object.assign({},d1)
深拷贝全部拷贝所有属性
var a2=JSON.parse(JSON.stringify(a1));
但是此方法无法复制函数类型
- 如果对象含有 toJSON 方法会调用 toJSON
- 在数组中
-
- 存在 Undefined/Symbol/Function 数据类型时会变为 null
-
- 存在 Infinity/NaN 也会变成 null
- 在对象中
-
- 属性值为 Undefined/Symbol/Function 数据类型时,属性和值都不会转为字符串
-
- 属性值为 Infinity/NaN ,属性值会变为 null
- 日期数据类型的值会调用 toISOString
- 非数组/对象/函数/日期的复杂数据类型会变成一个空对象
- 循环引用会抛出错误
自己写递归(很麻烦也不完整....特殊情况也用不了 算了)
function deepClone(obj) { //递归拷贝
if(obj === null) return null; //null 的情况
if(obj instanceof RegExp) return new RegExp(obj);
if(obj instanceof Date) return new Date(obj);
if(typeof obj !== 'object') {
//如果不是复杂数据类型,直接返回
return obj;
}
/**
* 如果obj是数组,那么 obj.constructor 是 [Function: Array]
* 如果obj是对象,那么 obj.constructor 是 [Function: Object]
*/
let t = new obj.constructor();
for(let key in obj) {
//如果 obj[key] 是复杂数据类型,递归
t[key] = deepClone(obj[key]);
}
return t;
}
使用第三方插件方法 像jQuery.extend lodash.js的cloneDeep
jQuery.extend([deep], target, object1, [objectN])
deep:如果设为true,则递归合并。
target:待修改对象。
object1:待合并到第一个对象的对象。
objectN:待合并到第一个对象的对象。
var data1 = {
a1: {
a11: [{
a111: "1",
a112: function () {
console.log("function")
}
}, ',']
}
};
var a2 = JSON.parse(JSON.stringify(a1));
/*var d3=Object.assign({},data1.a1);
d3.a11="123";*/
var a11 = $.extend(true, [], data1.a1.a11);
a11[0].a111 = "2";
a11[0].a112();//
// a2[0].a112()//error
console.log(data1.a1.a11[0].a111,a11[0].a111)
当然还有补充json.Stringify方法