-
方式一: 一个一个的拷贝
class Person{ name = "lnj"; age = 34; } let p1 = new Person(); let p2 = new Object(); p2.name = p1.name; p2.age = p1.age; p2.name = "zs"; console.log(p1.name); // lnj console.log(p2.name); // zs
-
方式二: 遍历对象
class Person{ name = "lnj"; age = 34; } let p1 = new Person(); for (let key in p1){ p2[key] = p1[key]; } console.log(p2); p2.name = "zs"; console.log(p1.name); // lnj console.log(p2.name); // zs
-
方式三: 使用Object对象中的assign方法
class Person{ name = "lnj"; age = 34; } let p1 = new Person(); // assign方法可以将第二个参数的对象的属性和方法拷贝到第一个参数的对象中 Object.assign(p2, p1); console.log(p2); p2.name = "zs"; console.log(p1.name); // lnj console.log(p2.name); // zs
以上三种深拷贝的方式并不是完全深拷贝, 只能将基本数据类型属性的拷贝, 而不能将引用数据类型数的拷贝
-
以上三种方式出现的问题
class Person{ name = "lnj"; cat = { age : 3 }; score = [1, 3, 5]; } let p1 = new Person(); let p2 = new Object(); // 基本数据类型属性的拷贝 p2.name = p1.name; p2.name = "zs"; console.log(p1.name); // lnj console.log(p2.name); // zs // 引用数据类型数的拷贝 // 此时p1和p2同时指向cat的存储空间, 所以这里实现不了深拷贝 p2.cat = p1.cat; p2.cat.age = 666; // 修改新变量的值会影响到原有变量, 这里是浅拷贝 console.log(p1.cat.age); // 666 console.log(p2.cat.age); // 666
-
解决办法 - 通过自定义函数实现深拷贝
class Person{ name = "lnj"; cat = { age : 3 }; score = [1, 3, 5]; } let p1 = new Person(); let p2 = new Object(); // 通过自定义函数实现深拷贝 function deCopy(target, source) { // 1.通过遍历拿到source中所有的属性 for (let key in source){ // 2.取出当前遍历到的属性对应的取值 let sourceValue = source[key]; // 3.判断当前的取值是否是引用数据类型 if (sourceValue instanceof Object){ // 如果是引用数据类型, 那么要新建一个存储空间保存 // 4.通过sourceValue.constructor拿到这个对象的构造函数的类型, 然后新建这个对象或数组 let subTarget = new sourceValue.constructor; target[key] = subTarget; // 5.再次调用拷贝, 将遍历到的属性的取值拷贝给新建的对象或者数组 deCopy(subTarget, sourceValue); }else { // 如果不是引用数据类型, 之间将属性拷贝即可 target[key] = sourceValue; } } } deCopy(p2, p1); p2.cat.age = 666; // 修改新变量的值不会影响到原有变量, 这里是深拷贝 console.log(p1.cat.age); // 3 console.log(p2.cat.age); // 666
网友评论