为什么 JavaScript 中的 getter 或 setter 不独立继承?

5 javascript oop inheritance getter-setter

考虑以下:

class Base {
   _value;
   constructor() {
      this._value = 1;
   }
   get value()  { return this._value; }
   set value(v) { this._value = v;    }
}
class Derived extends Base {
   set value(v) {
      // ...
      super.value = v;
   }
}
const d = new Derived();
d.value = 2;
console.log(d.value); // <-- undefined
Run Code Online (Sandbox Code Playgroud)

我期望该类的“getter”方法在 的类中“Base继承Derived,从而显示 的值2而不是undefined。似乎“getter”或“setter”方法都不是独立继承的,而是被视为一个整体。从某种意义上说,如果重写的 setter 方法不存在,或者它与相应的 getter 耦合(在派生类中专门声明,而不是被继承),如下所示:

get value() { return super.value; }
Run Code Online (Sandbox Code Playgroud)

那么就不会有这样的问题了。

那么,为什么 getter 或 setter 不独立继承,因为它们应该分离读取设置字段的概念?

Chr*_*ras 2

JavaScript\xe2\x80\x99s 类继承使用原型链将子级连接Constructor.prototype到父级Constructor.prototype以进行委派。通常,super()构造函数也会被调用。这些步骤形成单祖先父/子层次结构,并创建面向对象设计中最紧密的耦合。

\n\n

我建议您阅读一篇关于掌握 JavaScript 面试的非常好的文章:What\xe2\x80\x99s the Difference Between Class & Prototypal Inheritance?由埃里克·埃利奥特撰写。

\n\n

更新

\n\n

供详细说明;这是预期的行为,因为您正在向Derived.prototype. get当您使用或添加描述符时set,实际上会创建一个使用该名称的函数,因此如果未设置,它将评估为未定义。它变得像自己的财产一样。

\n\n
\n

标准 ECMA-262

\n\n

14.3.9运行时语义:PropertyDefinitionEvaluation

\n\n
    \n
  1. 方法定义set PropertyName ( PropertySetParameterList ) { FunctionBody }
  2. \n
  3. propKey为计算PropertyName的结果。\n ReturnIfAbrupt ( propKey )。
  4. \n
  5. 如果此MethodDefinition的函数代码是严格模式代码,则令stricttrue。否则让strictfalse
  6. \n
  7. 作用域正在运行的执行上下文\xe2\x80\x99s LexicalEnvironment
  8. \n
  9. formalParameterList成为产生式FormalParameters:[空]
  10. \n
  11. 闭包FunctionCreate (Method, PropertySetParameterList , FunctionBody , range , strict )。
  12. \n
  13. 执行MakeMethod (闭包,对象)。
  14. \n
  15. 执行SetFunctionName (闭包, propKey ,"set")。
  16. \n
  17. desc为 PropertyDescriptor{[[Set]]: closure , [[Enumerable]]: enumerable , [[Configurable]]: true }
  18. \n
  19. 返回DefinePropertyOrThrow (对象, propKey , desc )。
  20. \n
\n\n

6.2.4.6完整的属性描述符(描述)

\n\n

当使用Property Descriptor Desc调用抽象操作 CompletePropertyDescriptor 时调用抽象操作 CompletePropertyDescriptor 时,将执行以下步骤:

\n\n
    \n
  1. ReturnIfAbrupt描述)。
  2. \n
  3. 断言描述是一个属性描述符
  4. \n
  5. 设Record{[[Value]]: undefined , [[Writable]]: false , [[Get]]: undefined , [[ Set ]]: undefined , [[Enumerable]]: false , [[Configurable]] :错误的}。
  6. \n
  7. 如果IsGenericDescriptor (描述) 或IsDataDescriptor (描述) 为 true,则\n \n
      \n
    • A。如果Desc没有 [[Value]] 字段,请将Desc .[[Value]] 设置为like [[Value]]。
    • \n
    • b. 如果Desc没有 [[Writable]] 字段,请将Desc .[[Writable]] 设置为like [[Writable]]。
    • \n
  8. \n
  9. 否则,\n\n
      \n
    • A。如果Desc没有 [[Get]] 字段,请将Desc .[[Get]] 设置为like [[Get]]。
    • \n
    • b. 如果Desc没有 [[Set]] 字段,请将Desc .[[Set]] 设置为like [[Set]]。
    • \n
  10. \n
  11. 如果Desc没有 [[Enumerable]] 字段,请将Desc .[[Enumerable]] 设置为like [[Enumerable]]。
  12. \n
  13. 如果Desc没有 [[Configurable]] 字段,请将Desc .[[Configurable]] 设置为like [[Configurable]]。
  14. \n
  15. 返回描述
  16. \n
\n
\n\n

另请参阅表 5中的6.1.7.2 对象内部方法和内部槽- 基本内部方法,尤其是GetOwnPropertyDefineOwnProperty

\n\n
\n

[[GetOwnProperty]] (propertyKey) \xe2\x86\x92 未定义 | 属性描述符

\n\n

返回此对象自身属性的属性描述符,其键为propertyKeyundefined如果不存在此类属性,则返回

\n\n

[[DefineOwnProperty]] (propertyKey, PropertyDescriptor) \xe2\x86\x92 布尔值

\n\n

创建或更改自己的属性(其键为propertyKey )以具有PropertyDescriptor描述的状态。如果该属性已成功创建/更新,则返回true ,否则返回false;如果无法创建或更新该属性,则

\n
\n

  • 感谢您的更新,您能否详细说明唯一的问题:为什么 _getters_ 或 _setters_ 不(或不应该)独立继承。 (3认同)