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); // <-- undefinedRun 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 不独立继承,因为它们应该分离读取和设置字段的概念?
JavaScript\xe2\x80\x99s 类继承使用原型链将子级连接Constructor.prototype到父级Constructor.prototype以进行委派。通常,super()构造函数也会被调用。这些步骤形成单祖先父/子层次结构,并创建面向对象设计中最紧密的耦合。
我建议您阅读一篇关于掌握 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\n14.3.9运行时语义:PropertyDefinitionEvaluation
\n\n\n
\n\n- 方法定义:
\nsetPropertyName ( PropertySetParameterList ) { FunctionBody }- 令propKey为计算PropertyName的结果。\n ReturnIfAbrupt ( propKey )。
\n- 如果此MethodDefinition的函数代码是严格模式代码,则令strict为true。否则让strict为false。
\n- 令作用域为正在运行的执行上下文\xe2\x80\x99s LexicalEnvironment。
\n- 让formalParameterList成为产生式FormalParameters:[空]
\n- 令闭包为FunctionCreate (Method, PropertySetParameterList , FunctionBody , range , strict )。
\n- 执行MakeMethod (闭包,对象)。
\n- 执行SetFunctionName (闭包, propKey ,
\n"set")。- 令desc为 PropertyDescriptor{[[Set]]: closure , [[Enumerable]]: enumerable , [[Configurable]]: true }
\n- 返回DefinePropertyOrThrow (对象, propKey , desc )。
\n6.2.4.6完整的属性描述符(描述)
\n\n当使用Property Descriptor Desc调用抽象操作 CompletePropertyDescriptor 时调用抽象操作 CompletePropertyDescriptor 时,将执行以下步骤:
\n\n\n
\n- ReturnIfAbrupt(描述)。
\n- 断言:描述是一个属性描述符
\n- 设Record{[[Value]]: undefined , [[Writable]]: false , [[Get]]: undefined , [[ Set ]]: undefined , [[Enumerable]]: false , [[Configurable]] :错误的}。
\n- 如果IsGenericDescriptor (描述) 或IsDataDescriptor (描述) 为 true,则\n \n
\n\n
- A。如果Desc没有 [[Value]] 字段,请将Desc .[[Value]] 设置为like [[Value]]。
\n- b. 如果Desc没有 [[Writable]] 字段,请将Desc .[[Writable]] 设置为like [[Writable]]。
\n- 否则,\n\n
\n\n
- A。如果Desc没有 [[Get]] 字段,请将Desc .[[Get]] 设置为like [[Get]]。
\n- b. 如果Desc没有 [[Set]] 字段,请将Desc .[[Set]] 设置为like [[Set]]。
\n- 如果Desc没有 [[Enumerable]] 字段,请将Desc .[[Enumerable]] 设置为like [[Enumerable]]。
\n- 如果Desc没有 [[Configurable]] 字段,请将Desc .[[Configurable]] 设置为like [[Configurable]]。
\n- 返回描述
\n
另请参阅表 5中的6.1.7.2 对象内部方法和内部槽- 基本内部方法,尤其是GetOwnProperty和DefineOwnProperty。
\n\n[[GetOwnProperty]] (propertyKey) \xe2\x86\x92 未定义 | 属性描述符
\n\n返回此对象自身属性的属性描述符,其键为propertyKey或undefined如果不存在此类属性,则返回
\n\n[[DefineOwnProperty]] (propertyKey, PropertyDescriptor) \xe2\x86\x92 布尔值
\n\n创建或更改自己的属性(其键为propertyKey )以具有PropertyDescriptor描述的状态。如果该属性已成功创建/更新,则返回true ,否则返回false;如果无法创建或更新该属性,则
\n