【问题标题】:node Object.assign(obj1,obj2,obj3) returning the json properties of obj3node Object.assign(obj1,obj2,obj3) 返回 obj3 的 json 属性
【发布时间】:2018-04-27 12:28:11
【问题描述】:

我对 mongodb 有一些封装的 mongoose 查询。

collection1.findOne({ parm: value}, function(err, item){
    var a = item.a;
    var b = item.b;
    collection2.findOne({parm1: a}, function(err, item2){
        collection3.findOne({parm2: b}, function(err, item3){
            var records = Object.assign(item, item2, item3);
        });
    });
});

如果我在分配之前打印项目,项目 2 和项目 3,所有对象都会打印不同的以及一些相同的属性。当我在 var 记录行之后打印记录时,它只显示 item3 json 属性。

根据documentation 应该

将一个或多个源对象中所有可枚举的自身属性的值复制到目标对象。它将返回目标对象。

这没有发生。我做错了什么还是这是预期的行为?

我需要async 库。导入是否可能会改变 object.assign 的行为?

【问题讨论】:

  • 对象的键是否相等?
  • 有些是,有些不是
  • 它应该与最后一个值重叠,而不是只保留最后一个json对象属性
  • 好吧,那些相等的将是最后分配的那些,没有办法在一个对象中有两次相同的键。
  • 请记住 Object.assign 执行浅拷贝,因此如果对象被包装在单个键中。该单个键将被覆盖。例如:在Object.assign({}, {wrapper: {a:5, b:2}}, {wrapper: {b:3, c:2}}) 中,预期的输出是{wrapper:{b:3, c:2}},因为您正在用不同的对象替换整个包装键

标签: javascript json node.js mongodb mongoose


【解决方案1】:

当我在 var 记录行之后打印记录时,它只显示 item3 json 属性。

根据spec

iii) 如果 desc 不是未定义且 desc.[[Enumerable]] 为真,则

a) 设 propValue 为 Get(from, nextKey)。

b) ReturnIfAbrupt(propValue).

c) 让状态为 Set(to, nextKey, propValue, true)。 //观察这一行

d) ReturnIfAbrupt(状态)。

所以,这是一个预期的行为,因为 assign 的工作原理是

  • 分配值从左侧源到右侧
  • 并且不检查是否已设置属性

演示

var a = {a:1, b:2};
var b = {b:3, c:4};
var c = Object.assign( {}, a,b );
console.log(c); 

观察输出覆盖b属性

{ "a": 1, "b": 3, "c": 4 }

【讨论】:

  • 当我在 Object.assign 中添加 {} 时,我在对象周围得到了一个奇怪的包装器。让我用它更新我的问题。
  • @JoaoFilipeClementeMartins “奇怪的包装”是因为这些是“猫鼬文档”而不是“纯 JavaScript 对象”。您需要转换它们,即Object.assign({},item.toObject(),item2.toObject(),item3.toObject())。因此,虽然console.log() 使它们“出现”为普通对象,但它们根本不是。
  • @gurvinder372 我知道将为相同键设置的属性是分配函数中对象顺序的属性。但对我来说,它会丢失一些后续 json 对象中不存在的东西,这对我来说没有意义。
  • 不应该。您能在您的问题中分享item2item3 的值吗?
  • @gurvinder372 请检查我的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
  • 2013-09-26
  • 1970-01-01
  • 2012-07-30
  • 2019-09-05
相关资源
最近更新 更多