js对象深拷贝的最好的方法,实现js对象的深拷贝和浅拷贝

  js对象深拷贝的最好的方法,实现js对象的深拷贝和浅拷贝

  谈到javascript中的对象复制,我们首先想到的是Object.assign()

  JSON.parse(JSON.stringify())和ES6的扩展操作符[.]

  因为在js中,=操作符不能创建对象的副本,只能创建对象的引用。

  

运算符

   var x={

  答:1,

  乙:2,

  };

  y=x;

  x.a=10

  console . log(x);//{a:10,b:2}

  console . log(y);//{a:10,b:2}所以运算符等号(=)在执行对象运算时是不可取的。

  

Object.assign()

   var x={

  答:1,

  乙:2,

  };

  y=Object.assign({},x);

  x.a=10

  console . log(x);//{a:10,b:2}

  console . log(y);//{a:1,b:2}乍一看,我们不会发现任何异常,因为我们想要的就是我们想要的结果。我们先把对象结构做得复杂一点再看。

  var x={

  答:1,

  乙:2,

  丙:{

  d: 3,

  },

  };

  y=Object.assign({},x);

  x . a=5;

  console . log(x);//{a:5,b:2,c:{d:3}}

  console . log(y);//{a:5,b:2,c:{d:3}}

  x . c . d=10;

  console . log(x);//{a:5,b:2,c:{d:10}}

  console . log(y);//{a:5,b:2,c:{d:10}}这个时候就发现坑了,所以已经证明Object.assign()只是对象的浅拷贝。

  关于Object.assign()需要注意的另一点是,原型链上属性的不可枚举对象不能被复制。看一下代码:

  var x={

  答:1,

  };

  var y=Object.create(x,{

  乙:{

  值:2,

  },

  丙:{

  值:3,

  可枚举:真,

  },

  });

  var z=Object.assign({},y);

  console . log(z);//{c:3}得到Z的值很意外,因为X是Y的原型链,所以X不会被复制。

  b属性是可枚举属性,不会被复制。

  只有C有可枚举的描述,才能被枚举,所以可以复制。

  上面的坑也可以很好的解决,往下看:

  

深拷贝JSON.parse(JSON.stringify())

  解决浅抄的坑

  var x={

  答:1,

  乙:2,

  丙:{

  d: 3,

  },

  };

  y=JSON . parse(JSON . stringify(x));

  x . a=5;

  x . c . d=10;

  console . log(x);//{a:5,b:2,c:{d:10}}

  console . log(y);//{a:1,b:2,c:{d:3}}当然,对于普通对象来说,这种复制方式基本是完美的,那么他的坑在哪里呢?

  var x={

  答:1,

  b:函数b() {

  返回“2”;

  },

  };

  y=JSON . parse(JSON . stringify(x));

  z=Object.assign({},x);

  console . log(y);//{a:1}

  console . log(z);//{A: 1,B: Function B () {return 2}}从结果来看,Object.assign()可以复制方法,而JSON.parse(JSON.stringify())不能。

  看第二个坑:

  var x={

  答:1,

  乙:{

  c: 2,

  d: 3,

  },

  };

  x . c=x . b;

  x . d=x . a;

  x . b . c=x . c;

  x . b . d=x . d;

  var y=JSON . parse(JSON . stringify(x));

  console . log(x);

  /*

  未捕获的类型错误:将循环结构转换为JSON

  在JSON.stringify(匿名)

  匿名时间:8点25分

  */报错,结果显示JSON.parse(JSON.stringify())无法复制循环引用对象。

  让我们来看看Object.assign()

  var x={

  答:1,

  乙:{

  c: 2,

  d: 3,

  },

  };

  x . c=x . b;

  x . d=x . a;

  x . b . c=x . c;

  x . b . d=x . d;

  var y=Object.assign({},x);

  console . log(x);

  /*

  [对象对象]{

  答:1,

  乙:[对象,对象],

  d:[对象,对象],

  d:1

  }

  */

使用展开操作符[... ]

  对象文字的扩展运算符是ECMAScript的第三阶段提案,它使得复制对象变得更加容易。

  var x=[

  一个,

   b ,

  c ,

  d ,

  {

  e: 1,

  },

  ];

  var y=[.x];

  console . log(y);//[a , b , c , d ,{e:1}]

  var m={

  答:1,

  乙:2,

  c: [d , e],

  };

  var n={

  .m,

  };

  console . log(n);//{a:1,b:2,c:[d , e]}需要注意的是,expand运算符也是浅拷贝。那么,复制物体真的有那么难吗?

  

自己造轮子:

  功能副本(x) {

  var y={ };

  对于(x中的m){

  y[m]=x[m];

  }

  返回y;

  }

  var o={

  答:1,

  乙:2,

  丙:{

  d: 3,

  e: 4,

  },

  };

  var p=copy(o);有人说应该问题不大。那我们只能呵呵,继续走。

  var x={ };

  Object.defineProperty(x, m ,{

  价值:5,

  可写:假,

  });

  console . log(x . m);//5

  x.m=25//这一步没有报错,但是没有执行。

  console . log(x . m);//5这种情况下,扩展运算符在这里复制对象时也会遇到坑。

  到处都是坑,防不胜防.我写到这里还有很多坑没有完全列出来。

  以后再写吧。

  [结束]

  推荐:JavaScript视频教程以上是深入分析JavaScript中对象复制方法(附代码)的详细内容。更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: