循环给数组里的对象赋值

这个题目听起来有点别扭,但是其实也挺常见的。最实在的一个场景就是,你构建了一个数组,数组元素是对象,但是这些对象的结构体都是一样的,唯一不一样的就是每个键的值。要是觉得乱,请看小栗子:

var a = [{c: ' ',d: ' '},{c: ' ', d: ' ' }, {c: ' ' ,d: ' ' }];

一看到这个首先想到的肯定是for循环了,好的,没错,本文也是采用这种思路。顺着思路往下写就是这样的

//设定数组长度
var len = 9;
//设定结构体
var a = {
    c: ' ',
    d:' '
};
var b = new Array();
for(var i = 0; i < len; i++) {
    a.c = i;
    a.d = i+1;
//将对象循环放进数组中
    b.push(a);
    console.log(b[i].c);
}
console.log(b[3].c);
console.log(b[4].c);

嘻嘻,猜猜这三个log里边的数据。
不卖关子地说答案如下:
0-8
8
8
第一次看到这个结果的,我怎么也想不明白,为什么循环体内外的数据是不一样。这样的话,根本无法完成循环给数组内的对象赋值的任务了。后来查了很多东西,才看清了本质:对象的深复制与浅复制。因为对象a是预先定义好的,循环push进数组b的都是同一个对象a,所以当for循环里重新赋值的时候,每一个对象a都会变成一样的值。
其实在此之前,我是知道深复制和浅复制的,但是我根本没往这方面去注意,大概还是资质过浅,无法一眼识别。
关于深浅赋值,网上有很多的相关内容,在此贴出我认为好理解的概念。

浅复制:复制了对象的地址,只要改变其中一个,其他的都会被改变
深复制:复制了整个对象,不会彼此牵连

找出原因之后,就很容易对症下药了。

var len = 9;
var a = {
   c: ' '
};
var b = new Array();
for(var i = 0; i < len; i++) {
   var a = {
       c: ' ',
       d:' '
       };
   a.c = i;
   a.d = i+1;
   b.push(a);
   console.log(b[i].c); //0-8
}
console.log(b[3].c);//3
console.log(b[4].c);//4

也许还有其他方法,但总归是一个道理,破除了浅复制,你就赢了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容