学得语言过多而又没消化,所以很多东西是很混乱的,就本题(深复制,浅复制与赋值)的概念来说,所有语言都有(目前接触到的一些语言),但是语言特性原因总有不同吧。本文做个记录。关于JS的深复制,浅复制与赋值。
JS中数据类型分基本类型和引用类型(可以参考其它强类型语言的思维考虑),基本类型赋值时传值,引用类型传引用。
var x=10;
var y=x;
console.log(x,y); // 10 10
y=21;
console.log(x,y); //10 21
//x类型是引用故赋值给y后,x,y同指一片内存空间。
var x={age:10};
var y=x;
console.log(x.age,y.age); // 10 10
y.age=20;
console.log(x.age,y.age); //20 20
需求提出:我现在需要把对象x的值赋值给y。意思就是:x,y指向的内存空间不要让他相同。
//ES5写法:
var x={age:10,name:[1,2,3]};
function cloneObj(arg){
var result={};
for (var variable in arg) {
if (arg.hasOwnProperty(variable)) {
result[variable]=arg[variable];
}
}
return result;
}
var y=cloneObj(x);
console.log(x.age,y.age); // 10 10
y.age=20;
console.log(x.age,y.age); //10 20
//BUT有问题,x的属性中出现了引用类型
y.name.push(0);
console.log(x.name,y.name); //[ 1, 2, 3, 0 ] [ 1, 2, 3, 0 ]
//ES6写法:
var z=Object.assign({},x)
z.name.push(21);
console.log(z.name,x.name); //[ 1, 2, 3, 0, 21 ] [ 1, 2, 3, 0, 21 ]
注:ES6兼容性 --! 好吧,babel解决了 --!
上面的浅复制出现了一个问题,x的属性中出现了引用类型。这导致y,z中的name属性指向的是同一片地址空间。
所以:console.log(z.name,x.name,y.name); //[ 1, 2, 3, 0, 21 ] [ 1, 2, 3, 0, 21 ] [ 1, 2, 3, 0, 21 ]
所以给出深复制的意义:在复制一个对象时它的属性存在引用类型。
为了解决这个问题:思路(遍历x时,判断每个属性的类型,如果是引用类型的则递归调用)
//ES5写法:
var x={age:10,name:{nn:21}};
function cloneObj(arg){
var result={};
for (var variable in arg) {
if (arg.hasOwnProperty(variable)) {
if (typeof arg[variable]==='object') {
result[variable]=cloneObj(arg[variable]);
}else {
result[variable]=arg[variable];
}
}
}
return result;
}
var y=cloneObj(x);
y.name.nn=909;
console.log(x.name.nn,y.name.nn); //21 909
//ES6写法:嗯,就是两个JSON转对象,对象转JSON的API方法
var obj = {a: {b: 1}}
var copy = JSON.parse(JSON.stringify(obj))
obj.a.b = 2
console.log(obj) // {a: {b: 2}}
console.log(copy) // {a: {b: 1}}
注:
1. 深复制我主要是想说ES6的方式;
2. 我把上面的例子中x改了,之前name是个数组,现在是个对象。为什么?
JS中对象的复制过为麻烦,对象中属性为引用,但是JS里引用也是分很多的啊,例如:Array,function,RegExp…
例如上面ES6深复制方式就不能对function和RegExp类型进行复制,以及JSON.stringify搞不定循环引用的问题。
注:关于深浅复制的问题还有很多每展开讨论,但是感觉实际中用到的也就差不多上述说的一点。
不止是这两个库,还有些库也对深复制进行了实现,具体的实现代码自己找。
lodash中针对不同引用类型(例:array)传参做相应深复制处理。具体参见相应源码。
Jquery中的…..具体略
注:嗯,想做个工具库,就像lodash这种性质的,有兴趣欢迎pr。传送门
(我不是陈X,我也为自己代言。)
感觉有很多东西(例:鱼腥草|折耳根)吃一口恶心,不消化。多吃几次就好吃了??不,你习惯了。 千里行前莫死于足下!!!
百度里你能看到的相关文章
注:网络中的博客水平参差不齐,且看且思考!