【问题标题】:javascript primitives vs object referencesjavascript原语与对象引用
【发布时间】:2023-03-21 16:10:02
【问题描述】:

我已经使用 JavaScript 多年了,这让我很困惑。据我了解,在定义var 时,会发生以下两种情况之一:

  1. 如果表达式是原语,var 被定义为该原语的新实例,不引用传递的表达式。
  2. 如果表达式是对象字面量,则会创建一个新对象。
  3. 如果表达式是现有对象,var 将引用该对象,并且将反映该对象的任何未来更改。

但是,我遇到了案例 3​​ 不适用的情况:

var obj = {body: {'a': 1, 'b': 2, 'c': 3}};

var ref = obj.body;
ref = JSON.stringify(ref);

console.log(typeof ref); // string
console.log(typeof obj.body); // object

由于ref 被定义为objbody 属性,我认为将ref 重新定义为字符串也会影响obj.body。那我错过了什么?

【问题讨论】:

  • 你覆盖了变量,它不会改变对象中的内容......
  • 我认为混淆来自ref = ... 不会改变它指向的对象这一事实。如果您对ref 进行了变异(例如通过设置ref.a = 5),您将通过两个引用看到更新。

标签: javascript variables object reference primitive


【解决方案1】:

JSON.stringify 是一个接受对象并返回其字符串表示的方法,它不会改变任何东西。通过执行 ref = x 可以使 ref 指向另一件事,它不会影响分配之前的内容。

【讨论】:

  • 我还是一头雾水。如果ref引用obj.body,然后我做了ref = 'foo',那obj.body不会被重新定义为'foo'吗?
【解决方案2】:

这只是意味着,您不再引用 obj.body.body 并引用其他内容。

var ref = obj.body; 

//ref holding obj.body now any changes to ref will effect obj.body.

ref = JSON.stringify(ref);

//ref holding a String returned by `stringify()` now any changes to ref will effect obj.body.

你看到了吗?您只需将 ref 更改为不同的值。 obj 上并没有真正改变任何东西

【讨论】:

    【解决方案3】:

    原语是不可变的。如果与对象相比它们的行为方式有所不同,您将无法观察到这一点,因此请忘记所有有关复制的内容。让我们从“事物”的角度来讨论吧!对象和原语都是事物。当您将事物分配给变量时,您不会复制事物。

    var x = literally any value;
    var y = x;
    

    xy 都是包含相同内容的变量。如果你改变了这个东西,你以后从哪里访问它都没有关系;事情变了。如果你改变了变量包含的东西,它之前包含的东西不受影响。

    var z = some other value;
    y = z;  // y now contains the same thing as z instead of the same thing as x
            // only variables changed, and the things did not
    

    有很多答案用其他术语谈论这个,但我喜欢技术语言。

    tl;dr:出于所有意图和目的,JavaScript 中对象和基元之间的区别没有用处。

    ts;iwrseThis article about Python 同样适用于 JavaScript。

    【讨论】:

    • 长格式 cmets ftw
    猜你喜欢
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 2011-08-09
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多