js对象深拷贝的最好的方法,实现js对象的深拷贝和浅拷贝
谈到javascript中的对象复制,我们首先想到的是Object.assign()
JSON.parse(JSON.stringify())和ES6的扩展操作符[.]
因为在js中,=操作符不能创建对象的副本,只能创建对象的引用。
运算符
var x={
答:1,
乙:2,
};
y=x;
x.a=10
console . log(x);//{a:10,b:2}
console . log(y);//{a:10,b:2}所以运算符等号(=)在执行对象运算时是不可取的。
Object.assign()
var x={
答:1,
乙:2,
};
y=Object.assign({},x);
x.a=10
console . log(x);//{a:10,b:2}
console . log(y);//{a:1,b:2}乍一看,我们不会发现任何异常,因为我们想要的就是我们想要的结果。我们先把对象结构做得复杂一点再看。
var x={
答:1,
乙:2,
丙:{
d: 3,
},
};
y=Object.assign({},x);
x . a=5;
console . log(x);//{a:5,b:2,c:{d:3}}
console . log(y);//{a:5,b:2,c:{d:3}}
x . c . d=10;
console . log(x);//{a:5,b:2,c:{d:10}}
console . log(y);//{a:5,b:2,c:{d:10}}这个时候就发现坑了,所以已经证明Object.assign()只是对象的浅拷贝。
关于Object.assign()需要注意的另一点是,原型链上属性的不可枚举对象不能被复制。看一下代码:
var x={
答:1,
};
var y=Object.create(x,{
乙:{
值:2,
},
丙:{
值:3,
可枚举:真,
},
});
var z=Object.assign({},y);
console . log(z);//{c:3}得到Z的值很意外,因为X是Y的原型链,所以X不会被复制。
b属性是可枚举属性,不会被复制。
只有C有可枚举的描述,才能被枚举,所以可以复制。
上面的坑也可以很好的解决,往下看:
深拷贝JSON.parse(JSON.stringify())
解决浅抄的坑
var x={
答:1,
乙:2,
丙:{
d: 3,
},
};
y=JSON . parse(JSON . stringify(x));
x . a=5;
x . c . d=10;
console . log(x);//{a:5,b:2,c:{d:10}}
console . log(y);//{a:1,b:2,c:{d:3}}当然,对于普通对象来说,这种复制方式基本是完美的,那么他的坑在哪里呢?
var x={
答:1,
b:函数b() {
返回“2”;
},
};
y=JSON . parse(JSON . stringify(x));
z=Object.assign({},x);
console . log(y);//{a:1}
console . log(z);//{A: 1,B: Function B () {return 2}}从结果来看,Object.assign()可以复制方法,而JSON.parse(JSON.stringify())不能。
看第二个坑:
var x={
答:1,
乙:{
c: 2,
d: 3,
},
};
x . c=x . b;
x . d=x . a;
x . b . c=x . c;
x . b . d=x . d;
var y=JSON . parse(JSON . stringify(x));
console . log(x);
/*
未捕获的类型错误:将循环结构转换为JSON
在JSON.stringify(匿名)
匿名时间:8点25分
*/报错,结果显示JSON.parse(JSON.stringify())无法复制循环引用对象。
让我们来看看Object.assign()
var x={
答:1,
乙:{
c: 2,
d: 3,
},
};
x . c=x . b;
x . d=x . a;
x . b . c=x . c;
x . b . d=x . d;
var y=Object.assign({},x);
console . log(x);
/*
[对象对象]{
答:1,
乙:[对象,对象],
d:[对象,对象],
d:1
}
*/
使用展开操作符[... ]
对象文字的扩展运算符是ECMAScript的第三阶段提案,它使得复制对象变得更加容易。
var x=[
一个,
b ,
c ,
d ,
{
e: 1,
},
];
var y=[.x];
console . log(y);//[a , b , c , d ,{e:1}]
var m={
答:1,
乙:2,
c: [d , e],
};
var n={
.m,
};
console . log(n);//{a:1,b:2,c:[d , e]}需要注意的是,expand运算符也是浅拷贝。那么,复制物体真的有那么难吗?
自己造轮子:
功能副本(x) {
var y={ };
对于(x中的m){
y[m]=x[m];
}
返回y;
}
var o={
答:1,
乙:2,
丙:{
d: 3,
e: 4,
},
};
var p=copy(o);有人说应该问题不大。那我们只能呵呵,继续走。
var x={ };
Object.defineProperty(x, m ,{
价值:5,
可写:假,
});
console . log(x . m);//5
x.m=25//这一步没有报错,但是没有执行。
console . log(x . m);//5这种情况下,扩展运算符在这里复制对象时也会遇到坑。
到处都是坑,防不胜防.我写到这里还有很多坑没有完全列出来。
以后再写吧。
[结束]
推荐:JavaScript视频教程以上是深入分析JavaScript中对象复制方法(附代码)的详细内容。更多请关注我们的其他相关文章!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。