JS深拷贝概念并不新鲜,但是真正要真正理解原理还是有点难度的。这也是JS语言精粹之一吧。
例子
let a = { name: 'demo', age: 18};let b = a;b.name = 'demo1';console.log(a); // 输出 {name: "demo1", age: 18}console.log(b); // 输出 {name: "demo1", age: 18}
因为JS对于对象的赋值使用的是浅拷贝,其中一个实例变量
的赋值会影响到所有指向该对象
的变量
解决方案
- 粗暴好使的
JSON.parse(JSON.stringify)
,缺点:丢失成员函数
Object.assign
,缺点:只有第一级深拷贝,子级对象依旧是浅拷贝
,例子如下:let a = {name:{demo:'1'}};let b = Object.assign({}, a);console.log(a); // 输出 {name:{demo:'1'}}console.log(b); // 输出 {name:{demo:'1'}}b.name.demo = '2';console.log(a); // 输出 {name:{demo:'2'}}console.log(b); // 输出 {name:{demo:'2'}}
手动实现原理
- 遍历待拷贝对象
- 判断当前值类型,如果是object类型且不是null(null也是object),则递归调用拷贝函数
- 如果当前值类型时null或者非object类型,直接return,退出本次递归
编码实现
function deepCopy(obj) { let result = obj; if(typeof obj === 'object' && obj !== null) { result = Object.prototype.toString.call(obj) === '[object Array]' ? []: {}; for(let prop in obj) { result[prop] = deepCopy(obj[prop]); } } return result;}
验证一下:
let a = {name:{demo:'1'}};let b = deepCopy(a);console.log(a); // 输出 {name:{demo:'1'}}console.log(b); // 输出 {name:{demo:'1'}}b.name.demo = '2';console.log(a); // 输出 {name:{demo:'1'}}console.log(b); // 输出 {name:{demo:'2'}}
更多精彩内容尽在我的博客一键直达