小言_互联网的博客

一次javascript深拷贝引发的深入思考

300人阅读  评论(0)

A同学和B同学因为一次js深拷贝发生的一次争执。

A同学:深拷贝是另一个对象占用另一块内存就行了,随手写出了如下代码:


  
  1. let a = {
  2. name: "lcy",
  3. age: 18
  4. };
  5. let b = Object.assign({}, a);
  6. console.log( JSON.stringify(b, null, 2));
  7. let c = {};
  8. for ( let key in a) {
  9. c[key] = a[key];
  10. }
  11. console.log( JSON.stringify(c, null, 2));
  12. b.name = "123";
  13. c.name = "456";
  14. console.log( JSON.stringify(a, null, 2));
  15. console.log( JSON.stringify(b, null, 2));
  16. console.log( JSON.stringify(c, null, 2));

 

B同学:突然一看这两种方法好像确实都是深拷贝,bc对象修改属性后对a对象没什么影响,但是也会面临其他问题,如下


  
  1. let a = {
  2. name: "lcy",
  3. age: 18,
  4. user: {
  5. u: "uu_c"
  6. }
  7. };
  8. let b = Object.assign({}, a);
  9. let c = {};
  10. for ( let key in a) {
  11. c[key] = a[key];
  12. }
  13. b.user.u = "123";
  14. console.log( JSON.stringify(a));
  15. console.log( JSON.stringify(b));
  16. console.log( JSON.stringify(c));
  17. c.user.u = "456";
  18. console.log( JSON.stringify(a));
  19. console.log( JSON.stringify(b));
  20. console.log( JSON.stringify(c));

我们会发现,这种方式如果属性值是对象的话,那么这个对象是浅拷贝的,并么有完全深拷贝。

于是A同学灵机一动,迅速展示思维能力,随手就是一个代码~


  
  1. let a = {
  2. name: "lcy",
  3. age: 18,
  4. user: {
  5. u: "uu_c"
  6. }
  7. };
  8. function deepClone(obj) {
  9. let res = {};
  10. for ( let key in obj) {
  11. res[key] = typeof obj[key] == "object" ?
  12. deepClone(obj[key]) : obj[key];
  13. }
  14. return res;
  15. }
  16. let b = deepClone(a);
  17. console.log( JSON.stringify(a));
  18. console.log( JSON.stringify(b));
  19. b.user.u = "123";
  20. console.log( JSON.stringify(a));
  21. console.log( JSON.stringify(b));

A同学拍拍胸脯,搞定,然后B同学问,万一你这个拷贝的源对象属性是它原型上的呢?我们可能并不需要原型上的属性

A同学:那就在for循环的时候加一个判断,if(obj.hasOwnProperty(key))就行了,其他代码不用动,这个可难不倒我。

B同学:你要不加个数组到a对象试试,如下


  
  1. let a = {
  2. name: "lcy",
  3. age: 18,
  4. user: {
  5. u: "uu_c"
  6. },
  7. arr: [ 1, 3, 5]
  8. };
  9. function deepClone(obj) {
  10. let res = {};
  11. for ( let key in obj) {
  12. if (obj.hasOwnProperty(key)) {
  13. res[key] = typeof obj[key] == "object" ?
  14. deepClone(obj[key]) : obj[key];
  15. }
  16. }
  17. return res;
  18. }
  19. let b = deepClone(a);
  20. console.log( JSON.stringify(a));
  21. console.log( JSON.stringify(b));

这一下把A同学干懵了,居然数组还有这一情况,typeof 数组类型也是object,看来不能简单的判断object类型,于是A同学深思熟虑之后终于写出了如下代码 


  
  1. let a = {
  2. name: "lcy",
  3. age: 18,
  4. user: {
  5. u: "uu_c"
  6. },
  7. arr: [ 1, 3, 5]
  8. };
  9. function deepClone(obj) {
  10. let res = obj instanceof Array ? [] : {};
  11. for ( let key in obj) {
  12. if (obj.hasOwnProperty(key)) {
  13. res[key] = typeof obj[key] == "object" ?
  14. deepClone(obj[key]) : obj[key];
  15. }
  16. }
  17. return res;
  18. }
  19. let b = deepClone(a);
  20. console.log( JSON.stringify(a));
  21. console.log( JSON.stringify(b));

最后B同学看了一下,反手一巴掌对着A的后脑勺狠狠地给他点了个赞,说干得漂亮!

 

关注、留言,我们一起学习。

===============Talk is cheap, show me the code================


转载:https://blog.csdn.net/qq_34115899/article/details/108299664
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场