【问题标题】:Assignment behavior differs for whole object and its attributes [duplicate]整个对象及其属性的分配行为不同[重复]
【发布时间】:2016-11-20 21:06:44
【问题描述】:

例如,我们有以下 JavaScript 代码:

function f(o) {
    o.message = "set in f";
    o = {
        message: "new object!"
    };
    console.log(`inside f: o.message="${o.message}" (after assignment)`);
}
let o = {
    message: 'initial value'
};
console.log(`before calling f: o.message="${o.message}"`);
f(o);
console.log(`after calling f: o.message="${o.message}"`);

在这些特定的行中

o = {
    message: "new object!"
};

我们正在创建名为“o”的新对象,但在上一行

o.message = "set in f";

我们正在修改名称为“o”的原始对象的属性(因此在我的理解中修改了对象本身)。

我的问题是为什么在这些情况下分配行为会有所不同?对象本身及其属性不应该一样吗?

例如,函数体中的 'o' 赋值应该改变原始的 'o' 对象而不是创建新对象。

【问题讨论】:

  • 不...非常简单的例子是{} != {}。每个都是一个新对象,没有引用另一个

标签: javascript object syntax assign


【解决方案1】:

如果你仔细想想,这两种情况的行为实际上都非常相似。请记住,o.message 在您将 "set in f" 分配给它时已经存在。新值将覆盖o.message 的现有值"initial value",就像将对象字面量分配给变量o 时会覆盖先前的值,而它已经存在。

如果你从上下文来看,同样的说法是正确的。如果o是一个全局变量,它实际上(在某种程度上)可以被看作是全局对象上的一个属性,在浏览器中是window。因此,如果 window.o 已经存在,并且您执行类似 o = {} 的赋值(在此示例中与 window.o = {} 相同),则行为是相同的。

在所有情况下,当您覆盖变量或属性的现有值时,您同时修改了变量或属性所在的上下文。这只是一个视角问题。

【讨论】:

  • 很好的解释。唯一的区别是对象是语言值并且可以传递,而变量环境不是可访问的实体。
  • 非常感谢您的解释!
猜你喜欢
  • 1970-01-01
  • 2021-12-04
  • 2020-01-15
  • 2017-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-03
  • 2016-10-14
相关资源
最近更新 更多