【问题标题】:Javascript spread & inheritanceJavascript 传播与继承
【发布时间】:2019-02-09 07:14:02
【问题描述】:

我对 javascript 开发还很陌生,仍在学习概念。我有一个关于传播“操作员”的问题 (...)。 它可以用作类似继承的机制还是有副作用让我避免这种情况?

示例

const A = {
  prop1: "value1",
  prop2: function() {return this.prop1}
}

const B = {
  ...A,
  prop1: "updated_value1",
  prop3: "value3"
}

这里可以看到 B 是从 A 继承的,A.prop2() 返回 value1,而B.prop2() 返回 updated_value1 可以期待任何继承的对象。

这有效吗?

【问题讨论】:

  • 抛出错误
  • 没有。 B在使用展开语法时不包含Aprototype链,只有它自己的属性。

标签: javascript inheritance spread-syntax


【解决方案1】:

您发布的代码按预期工作,因为 A 的属性被复制到 B。但是,这不是继承的示例,它只是一个浅拷贝。

在您的示例中,所有属性都是原语,考虑如果我们添加对 A 的引用会发生什么:

const A = {
  prop1: "value1",
  prop2: function() {return this.prop1},
  obj: { value: 1 }
}

const B = {
  ...A,
  prop1: "updated_value1",
  prop3: "value3"
}

现在,更改A.obj.value 也将修改B.obj.value,这实际上将使所有B 与A 共享他们的obj 并在他们之间共享。这在某些情况下可能很有用,但它不完全是继承。

对于继承最好使用"Javascript classes"

【讨论】:

    【解决方案2】:

    在您的情况下,我倾向于使用 Object Assign,因为出错的可能性较小:

    const A = {
      prop1: "value1",
      prop2: function() {return this.prop1}
    }
    
    cont B = Object.assign(A, {
      prop1: "updated_value1",
      prop3: "value3"
    });
    

    但这仍然不是真正的继承。

    【讨论】:

      【解决方案3】:

      它可能看起来像继承,但实际上你所定义的只是:

      const A = {
        prop1: "value1",
        prop2: function() {return this.prop1}
      }
      
      const B = {
        prop1: "value1",
        prop2: function() {return this.prop1},
        prop1: "updated_value1",
        prop3: "value3"
      }
      

      本质上,您正在覆盖为对象 B 定义的 2 行的成员。 它不是继承,因为成员的定义将由对象 B 拥有,而不是 B 的原型。当引用 B.prop1 时,引擎将不必查看属性的原型,如果您使用原型,继承会这样做

      【讨论】:

        【解决方案4】:

        你不能真正称之为固有。这是一个合并。通过写这个

        const B = {
          ...A,
          prop1: "updated_value1",
          prop3: "value3"
        }
        

        来自 A 的props1 将被来自 B 的 prop1 覆盖。所以是的,B.prop2() 将返回 updated_value1,这是完全公平的。

        【讨论】:

        • 是的,在 Chrome 控制台中尝试。
        【解决方案5】:

        我不会称之为继承。使用对象的扩展运算符类似于使用 Object.assign()。该方法的作用是将所有可枚举的自身属性的值从一个或多个源对象复制到目标目的。 见documentation

        【讨论】:

          【解决方案6】:

          {...A} 只是从“A”创建所有键值的副本并将其设置为“B”。 然后将“B”的属性 prop1 更新为 updated_value1。 “A”保持不变。这是完全有效的

          【讨论】:

            猜你喜欢
            • 2017-03-23
            • 2012-10-13
            • 1970-01-01
            • 2013-11-07
            • 2014-08-08
            • 1970-01-01
            • 2015-10-12
            • 2012-10-30
            • 2010-10-30
            相关资源
            最近更新 更多