Javascript对象的深度分配不起作用(NodeJS)

时间:2014-08-05 11:58:51

标签: javascript node.js underscore.js sails.js waterline

我想做什么 我试图使用映射函数深度重新映射现有的对象数组。 它可以在下面的“输出1”中看到它自己的映射,但是对象的深度分配不起作用,这意味着它没有发生(参见“输出2”)。

(背景)不那么重要的信息: (由于水线中的“深度人口”约束(sailsJS),我试图使用async的auto手动进行填充)

    var roomsMapper = _.indexBy(results.rooms, 'id'); // maps id to a new room object that has array of children
    _.each(data.centers, function (center, index) {
        var mappedRooms = _.map(center.rooms, function (room) {
            return roomsMapper[room.id];
        });

        sails.log.info("mappedRooms: ", mappedRooms); // as expected see output 1
        data.centers[index].rooms = mappedRooms;
        sails.log.info("data.centers[index]: ", data.centers[index]); // not as expected, see output 2
    });

    sails.log.info("data.centers: ", data.centers); // new values are not assigned

output1(映射值包含子项数组):

info: mappedRooms:  [ { children:
     [ { name: 'Child Khoury',
         birthday: Sun Dec 28 2008 00:00:00 GMT+0200 (Jerusalem Standard Time),
         sex: 'M',
         allergies: null,
         id: '53dff26a3e5cb1b01f2f2e13',
         createdAt: Mon Aug 04 2014 23:51:54 GMT+0300 (Jerusalem Summer Time),
         updatedAt: Mon Aug 04 2014 23:51:54 GMT+0300 (Jerusalem Summer Time),
         room: '53dff0205c89c03428a31cf0' },
       { name: 'Ashqar Sameeh',
         birthday: Tue Feb 01 2000 00:00:00 GMT+0200 (Jerusalem Standard Time),
         sex: 'F',
         allergies: null,
         id: '53dff2803e5cb1b01f2f2e14',
         createdAt: Mon Aug 04 2014 23:52:16 GMT+0300 (Jerusalem Summer Time),
         updatedAt: Mon Aug 04 2014 23:52:16 GMT+0300 (Jerusalem Summer Time),
         room: '53dff0205c89c03428a31cf0' } ],
    center: '53dff0205c89c03428a31cee',
    name: 'sydney room2',
    min_age: 5,
    max_age: 7,
    createdAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
    updatedAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
    id: '53dff0205c89c03428a31cf0' },
  { children:
     [ { name: 'Samih Samama',
         birthday: Mon Dec 29 2008 00:00:00 GMT+0200 (Jerusalem Standard Time),
         sex: 'M',
         allergies: [Object],
         id: '53dff29e3e5cb1b01f2f2e16',
         createdAt: Mon Aug 04 2014 23:52:46 GMT+0300 (Jerusalem Summer Time),
         updatedAt: Mon Aug 04 2014 23:52:46 GMT+0300 (Jerusalem Summer Time),
         room: '53dff0205c89c03428a31cef' } ],
    center: '53dff0205c89c03428a31cee',
    name: 'sydney room1',
    min_age: 0,
    max_age: 3,
    createdAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
    updatedAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
    id: '53dff0205c89c03428a31cef' } ]

output2(mappedRooms未分配 - 缺少子数组):

    info: data.centers[index]:  { rooms:
       [ { name: 'sydney room2',
           center: '53dff0205c89c03428a31cee',
           min_age: 5,
           max_age: 7,
           createdAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
           updatedAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
           id: '53dff0205c89c03428a31cf0' },
         { name: 'sydney room1',
           center: '53dff0205c89c03428a31cee',
           min_age: 0,
           max_age: 3,
           createdAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
           updatedAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
           id: '53dff0205c89c03428a31cef' } ],
      state: '53df76c278999310248072c6',
      name: 'Sydney Center',
      menuItems: null,
      createdAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
      updatedAt: Mon Aug 04 2014 23:42:08 GMT+0300 (Jerusalem Summer Time),
      id: '53dff0205c89c03428a31cee' }

2 个答案:

答案 0 :(得分:1)

对象分配是引用,而不是值。我使用以下方法将一个对象复制到另一个对象:

function extendObject(destination, source) {
  for (var property in source) {
    if (source[property] && source[property].constructor &&
     source[property].constructor === Object) {
      destination[property] = destination[property] || {};
      arguments.callee(destination[property], source[property]);
    } else {
      destination[property] = source[property];
    }
  }
  return destination;
};

所以,举个例子:

var obj1 = { a: { foo: 'bar' } };
var obj2 = { b: { bar: 'foo' } };
extendObject(obj2, obj1);
obj1.a.foo = "different";
console.log(obj1);
console.log(obj2);

输出:

{ a: { foo: 'different' } }
{ b: { bar: 'foo' }, a: { foo: 'bar' } }

[编辑] - 如果我正确理解问题,这基本上会做同样的事情:

var roomsMapper = _.indexBy(results.rooms, 'id');
_.each(data.centers, function (center, index) {
  var mappedRooms = [];
  for( i in center.rooms ) {
    mappedRooms.push(roomsMapper[center.rooms[i].id]);
  }
  data.centers[index].rooms = mappedRooms;
});

答案 1 :(得分:1)

我试过了,当你将中心传递给地图回调函数并修改其中一个属性时,无法真正理解为什么引用会丢失。

无论如何,以下内容对我有用:

    var roomsMapper = _.indexBy(results.rooms, 'id'); 
    var mappedCenters = _.map(data.centers, function (center) {
        var _center = center.toObject(); // create new object
        _center.rooms = _.map(center.rooms, function (room) {
            return roomsMapper[room.id];
        });
        return _center;
    });