JS对象的属性覆盖问题

推入数组时候对象变掉了

clipboard.png rows是用node-mysql取到的结果。

    for(var i of rows){
      var obj = {};
      var ar = [];
      if(i.name){
        obj.field_name = '1002';
        obj.field_value = '微信';
        obj.virtualAccount = i.id;
        console.log(obj);
        ar.push(obj);
        // obj = {}; 加上这行才正常
      }
      if (i.intro) {
        obj.field_name = '1001';
        obj.field_value = 'QQ';
        obj.virtualAccount = i.id;
        console.log(obj);
        ar.push(obj);
      }
      arr.push(ar);
    }
    console.log(arr);
    

clipboard.png 这是运行结果。为什么微信没有push进去呢

阅读 9k
5 个回答

你代码里不是自己写了么,被注释掉的那行加上就好了。

这里面还是对象引用的问题,ar.push(obj);第一个if里边push了微信的进去了,但是第二个if修改了obj的属性,所以第一个push进去的obj的属性就改变了,所以最终就是都变成第二次push进去的那个了

因为object,Array 为引用类型,举个栗子-

var a =[];
var b ={};
b.name = 'name1';
b.id = 1;

a.push(b);

b.name = 'name2'; //到这里 已经更改了原来的name值了
b.id = 2;

a.push(b);

LZ最好分离一下代码,在循环体外做一个 创建object的方法,例如:

var _createObject = function(row){

        var obj = {
            id   : row.id,
            name : row.name
        };
        return obj;
    }

然后在你循环里去执行该方法 var obj = _createObject(row);

再有, 你的数组也需要定义在循环体之外;

因为这里定义

for(var i of rows){
      var obj = {};
      var ar = [];
      if(i.name){
        obj.field_name = '1002';
        obj.field_value = '微信';
        obj.virtualAccount = i.id;
        console.log(obj);
        ar.push(obj);
        // obj = {}; 加上这行才正常
      }
      if (i.intro) {
        obj.field_name = '1001';
        obj.field_value = 'QQ';
        obj.virtualAccount = i.id;
        console.log(obj);
        ar.push(obj);
      }
      arr.push(ar);
    }
    console.log(arr);

这个for循环里面定义的。javascript ES5是没有块作用域的,所以你的你认为你的每次进到for都会清空一次obj对象,其实不是的,这个obj对象是在全局。所以你在push qq的时候已经改变了obj对象属性了。这样你明白了么?
我深入了一下js的原理给你解释。

你两个if都执行了吧。。。第一个if加的也被第二个if覆盖了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题