Object.assign的奇怪行为

3
我最近在JavaScript中尝试了一些Spread Syntax的操作,结果非常奇怪和疯狂,让我想要发布这个问题。我的理解是Spread Syntax类似于Object.assign(),但它是否会因为相同类型的变量而有所不同呢?

a = {a: "a"};
b = {b: "b"};
c = {c: "c"};
d = {d: {e: "e"}};

d = Object.assign(a, b, c, d);
e = { ...a, ...b, ...c, ...d };

console.log("Before Variable Change");
console.log(d);
console.log(e);

a.a = "s";
b.b = "t";
d.d.e = "f";

console.log("After Variable Change");
console.log(d);
console.log(e);
.as-console-wrapper {max-height: 100% !important; height: 100% !important;}

我得到的结果是:
Before Variable Change
{
  "a": "a",
  "b": "b",
  "c": "c",
  "d": {
    "e": "e"
  }
}
{
  "a": "a",
  "b": "b",
  "c": "c",
  "d": {
    "e": "e"
  }
}
After Variable Change
{
  "a": "s",
  "b": "b",
  "c": "c",
  "d": {
    "e": "f"
  }
}
{
  "a": "a",
  "b": "b",
  "c": "c",
  "d": {
    "e": "f"
  }
}

我理解到,因为 d.e 是一个“对象”,且可变,所以它的值会一直变化,这是可以接受的。但是,当我尝试使用 ... 扩展语法时,对象的第一个值(a.a)发生了改变,但第二个值(b.b)没有发生改变。我有遗漏什么吗?
额外信息:

在以下浏览器中进行了测试:

  • macOS 上的 Chrome,版本 71.0.3578.98(官方版本)(64 位)
  • Windows 上的 Chrome,版本 70.0.3538.110(官方版本)(32 位)

@Pointy 好的,我没有完全理解。你能解释一下吗? - Praveen Kumar Purushothaman
@Pointy 啊!正在更改它。 - Praveen Kumar Purushothaman
@Pointy 已更改。谢谢。:) - Praveen Kumar Purushothaman
你正在修改 a,而不是复制 a - dandavis
4
在执行 d = Object.assign(a, ...) 这行代码后,你感到困惑是因为此时 d === a - Bergi
显示剩余8条评论
1个回答

2
Object.assign()函数会修改第一个对象参数a的内容。它也是返回值,因此在第一次调用Object.assign()并设置d的值后,d === a将为真。
因此,“s”分配给a.a也会更改d.a,因为da引用同一个对象。
换句话说,展开运算符做的就是这个:
d = Object.assign({}, a, b, c, d);
e = { ...a, ...b, ...c, ...d };

现在上述两者是相同的。

在你的代码中,你在哪里更改a.bd.b?你只更改b.b,而对象b的“b”属性与对象d(和a)的“b”属性无关。 - Pointy
1
抱歉让你感到困惑;我误解了你的误解 :) - Pointy
哈哈哈...我现在明白了...这真的是一件令人困惑的事情还是只有我?所以现在我明白了Object.assign...不是同一个东西。 - Praveen Kumar Purushothaman
1
Object.assign({} [,other args/objs here]) 就像 spread 一样,它们的区别在于这个函数可以接受多个参数或对象。 - dandavis
@dandavis 经过长时间的努力,我终于明白了。谢谢你,伙计!:) - Praveen Kumar Purushothaman
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接