浅复制
关于普通数组或者对象的复制最简单的方式就是直接赋值
因为a和b指向同一个块内存 所以会修改b会影响a
123456var a = [1,2,3,4];var b = a;console.log(b); // =>[1,2,3,4]b.push(5);console.log(a); // => [1,2,3,4,5]console.log(b); // => [1,2,3,4,5]123456var a = {key:1};var b = a;console.log(a===b) // => trueb.key = 2;console.log(a.key) // => 2另一种直接的方法就是利用循环
123456789var a = [1,2,3,4];var b = [];for(let i in a){b[i] = a[i];}console.log(b); // => [1,2,3,4]b.push(5);console.log(a); // => [1,2,3,4]console.log(b); // => [1,2,3,4,5]利用slice属性和concat属性可以完成数组或对象的浅拷贝
123456var a = [1,2,3,4];var b = a.slice();console.log(b); // => [1,2,3,4]b.push(5);console.log(a); // => [1,2,3,4]console.log(b); // => [1,2,3,4,5]1234567var a = ["key",{count:1}];var b = a.slice(); // 返回一个a的浅拷贝对象a==b // => false b是a的一个实例b[0] = "game";console.log(a[0]); // =>"key" a和b中的基本类型值 复制的为副本 不会相互影响b[1].count = 2;console.log(a[1].count) // => 2 a和b中的引用类型值 指向相同利用Object.assign()
Object.assign() 方法可以把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。
123456789101112var x = {a:1,b:{f:{g:1}},c:[1,2,3]};var y = Object.assign({},x);console.log(y.b.f===x.b.f) // => true
实现一个关于对象的浅复制
在使用浅拷贝时如果改变子对象 并且属性恰好为一个对象 那么也自然会修改原对象
12345678910function shallowCopy(p,c){var i;c = c||{};for(i in p){if(p.hasOwnProperty(i)){c[i] = p[i];}}return c;}123456789var dad = {count:[1,2,3],game:{Inside:true}};var kid = shallowCopy(dad);kid.count.push(4);kid.count.toString(); // => "1,2,3,4"dad.count.toString(); // => "1,2,3,4"dad.game === kid.game; // => true
深复制
关于对象的深度复制 可实现继承
123456789101112131415function deepCopy(p,c){var i;c = c||{};for(i in p){if(p.hasOwnProperty(i)){if(typeof p[i]==="object"){c[i] = Array.isArray(p[i])?[]:{};deepCopy(p][i],c[i]);}else{c[i] = p[i];}}}return c;}上述代码在复制时会进行类型检查 如果复制对象为一个数组或者对象会递归的遍历属性对象并将属性元素复制出来
12345678910111213var dad = {count:[1,2,3],game:{Inside:true}};var kid = deepCopy(dad);kid.count.push(4);kid.count.toString(); // => "1,2,3,4"dad.count.toString(); // => "1,2,3"dad.game === kid.game; // => falsekid.game.Inside = false;kid.game.Limbo = true;dad.game.Inside; // => trueJSON对象的parse和stringify 也可实现深度复制
JOSN对象中的stringify可以把一个js对象序列化为一个JSON字符串,parse可以把JSON字符串反序列化为一个js对象 通过这两个方法 可以实现对象的深复制123456789101112var dad = {count:[1,2,3],game:{Inside:true}};var kid =JSON.parse(JSON.stringify(dad));kid.count.push(4);kid.count.toString(); // => "1,2,3,4"dad.count.toString(); // => "1,2,3"dad.game === kid.game; // => falsekid.game.Inside = false;kid.game.Limbo = true;dad.game.Inside; // => true