【问题标题】:Is function object created by `new` constructor treated as mutable object in javascript?由`new`构造函数创建的函数对象是否被视为javascript中的可变对象?
【发布时间】:2019-04-27 13:14:04
【问题描述】:

通过学习,我了解到在 javascript 中,可变对象() 由 call-by-reference 处理,而 不可变对象 是由按值调用调用约定处理。

假设我使用这种数据,

var Node = function(data) {
  this.data = data;
  this.next = null;
};

var v = new Node(0);

v是可变对象还是不可变对象??

【问题讨论】:

  • 什么是不可变对象?你是说原始类型吗?
  • JavaScript 中的每个参数都是按值传递的。你的变量是一个对象。
  • 它是可变的,因为您可以更改/添加/删除对象的属性
  • @Pointy 能不能多解释一下“JavaScript 中的每个参数都是按值传递的”。考虑一个函数const f = (x) => x 如果我们将一个对象{a:1} 传递给它。它将通过引用传递。
  • @MaheerAli 每个对象都是一个引用值,但每个参数仍然是按值传递的。如果你调用f(y),那么重新分配给x 并不能改变y 持有的内容。

标签: javascript calling-convention function-object


【解决方案1】:

JavaScript 没有“不可变对象”,有两种类型:

1) 原语 - 不可变

2) 对象 - 可变

更新:object freeze 可以给出一些“不可变”

【讨论】:

    【解决方案2】:

    首先让我们了解new operator在幕后创建的执行上下文中做了什么:

    它会:

    1. 创建一个新对象(并将其附加到this 标签)
    2. 新对象的__proto__ 属性将引用函数的prototype 属性
    3. 它将返回新创建的对象(如果您没有显式返回对象)

    所以在你的情况下:

    var v = new Node(0);
    

    v 实际上是一个Object(通过new 创建和返回的那个),JavaScript 中的对象是可变的。

    Here 是原始(不可变)类型:
    布尔

    未定义
    号码
    字符串
    符号(ECMAScript 6 中的新功能)

    【讨论】:

      【解决方案3】:

      它是可变的,正如您从这个工作示例中看到的那样。

      var Node = function(data) {
        this.data = data;
        this.next = null;
      };
      
      var v = new Node(0);
      
      v.myNewAttribute = 'foobar';
      
      var elemDiv = document.createElement('div');
      elemDiv.innerHTML = JSON.stringify(v);
      document.body.appendChild(elemDiv);

      【讨论】:

        【解决方案4】:

        v 是一个可变 对象。要将此对象更改为 不可变 对象,请使用 Object.freeze() 方法。

        示例:

        var Node = function(data) {
          this.data = data;
          this.next = null;
        };
        
        var v = new Node(0); // "v" object is mutable  
        v.data = 1;          // The "data" property value will change
        console.log(v);
        
        Object.freeze(v); // "v" object is immutable  
        
        v.data = 2;       // The "data" property value will NOT change
        
        console.log(v);

        Object.freeze() 方法冻结一个对象。无法再更改冻结的对象;冻结对象可防止向其添加新属性、删除现有属性、防止更改现有属性的可枚举性、可配置性或可写性,并防止更改现有属性的值。此外,冻结对象还可以防止其原型被更改。 freeze() 返回传入的相同对象。more

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-28
          • 1970-01-01
          • 2023-03-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-31
          相关资源
          最近更新 更多