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

为什么getter或setter不能在JavaScript中独立继承?,javascript,oop,inheritance,getter-setter,Javascript,Oop,Inheritance,Getter Setter,考虑以下几点: 类基{ _价值观; 构造函数(){ 该值为._值=1; } get value(){返回此值。_value;} 设置值(v){this.\u value=v;} } 类派生的扩展基{ 设定值(v){ // ... super.value=v; } } const d=新派生的(); d、 数值=2; console.log(d.value);// JavaScript的类继承使用原型链将子构造函数.prototype连接到父构造函数.prototype进行委托。通常,也会调用s

考虑以下几点:

类基{
_价值观;
构造函数(){
该值为._值=1;
}
get value(){返回此值。_value;}
设置值(v){this.\u value=v;}
}
类派生的扩展基{
设定值(v){
// ...
super.value=v;
}
}
const d=新派生的();
d、 数值=2;

console.log(d.value);// JavaScript的类继承使用原型链将子
构造函数.prototype
连接到父
构造函数.prototype
进行委托。通常,也会调用
super()
构造函数。这些步骤形成单一祖先父/子层次结构,并创建OO设计中可用的最紧密耦合

我建议你读一篇关于埃里克·艾略特的非常好的文章

更新

用于阐述;这是预期的行为,因为您正在将新描述符添加到
Derived.prototype
。当您使用
get
set
添加描述符时,实际上有一个使用该名称创建的函数,因此如果未设置,它将计算为未定义。它变成了自己的财产

标准ECMA-262 运行时语义:PropertyDefinitionEvaluation
  • 方法定义:
    set
    PropertyName(PropertySetParameterList){FunctionBody}
  • 让propKey作为计算PropertyName的结果。 (propKey)
  • 如果此MethodDefinition的函数代码为,则将strict设置为true。否则,将strict设置为false
  • 让范围成为’s
  • 让formalParameterList成为生产FormalParameters:[空]
  • 设闭包为(方法、PropertySetParameterList、函数体、范围、严格)
  • 执行(闭包、对象)
  • 执行(闭合、propKey、
    “设置”
  • 让desc成为PropertyDescriptor{[[Set]]:closure,[[Enumerable]]:Enumerable,[[Configurable]]:true}
  • 返回(对象、属性键、描述)
  • CompletePropertyDescriptor(描述) 使用Desc调用抽象操作CompletePropertyDescriptor时,将执行以下步骤:

  • (描述)
  • :Desc是一个
  • 比如记录{[[Value]]:未定义,[[Writable]]:,[[Get]]:未定义,[[Set]]:未定义,[[Enumerable]]:,[[Configurable]]:
  • 如果(Desc)或(Desc)为真,则
    • a。如果Desc没有[[Value]]字段,请将Desc.[Value]]设置为like.[Value]]
    • b。如果Desc没有[[Writable]]字段,请将Desc.[Writable]]设置为like.[Writable]]
  • 否则,,
    • a。如果Desc没有[[Get]]字段,请将Desc.[Get]]设置为like.[Get]]
    • b。如果Desc没有[[Set]]字段,请将Desc.[Set]]设置为like.[Set]]
  • 如果Desc没有[[Enumerable]]字段,请将Desc.[Enumerable]]设置为like.[Enumerable]]
  • 如果Desc没有[[Configurable]]字段,请将Desc.[Configurable]]设置为like.[Configurable]]
  • 返回说明
  • 还可以查看,尤其是
    GetOwnProperty
    DefineOwnProperty

    [[GetOwnProperty]](propertyKey)→ 未定义|
    返回此对象自身属性的属性描述符,其键为propertyKey,如果不存在此类属性,则返回未定义的属性描述符

    [[DefineOwnProperty]](propertyKey,PropertyDescriptor)→ 布尔值
    创建或更改自己的属性(其键为propertyKey),使其具有PropertyDescriptor描述的状态。如果成功创建/更新该属性,则返回true;如果无法创建或更新该属性,则返回false


    能干的描述符有一个获得者和一个设定者。没有acessor描述符,就不能有getter/setter<代码>派生。原型
    包含在
    派生
    中指定的
    的辅助描述符。这就是JavaScript的工作原理

    如果要继承getter,可以手动更改
    Derived
    的原型,如下所示:

    Object.defineProperty(派生的.prototype,“值”{
    get:Object.getOwnPropertyDescriptor(Base.prototype,“value”).get,
    set:Object.getOwnPropertyDescriptor(派生的.prototype,“值”).set
    });
    
    我看到的问题是使用super。如果您改为在子类的构造函数中使用super(),您将从父类获得所有方法,因此您不需要为子类中的值设置setter,因为它是继承的

    类基{
    _价值观;
    构造函数(){
    该值为._值=1;
    }
    get value(){返回此值。_value;}
    设置值(v){console.log('value in parent',v'),this.\u value=v;}
    }
    类派生的扩展基{
    构造函数(){
    超级();
    }
    }
    const d=新派生的();
    d、 数值=7;
    
    console.log(d.value);// 我想强调一下其他人已经说过的话:这就是Javascript的工作方式

    Javascript是在浏览器战争中锻造的。这是一组混乱的特性,选择时考虑了折衷和向后兼容性,而不是精心设计的语言

    因此,问“为什么能手和二传手会这样工作?”几乎就像问为什么:

    console.log(
    (![]+[])[+[]]+(![]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]
    )
    
    //===失败
    “因为他们应该解耦概念”-哪些概念?@Bergi读取和设置字段的概念。我认为这些概念之间的耦合度很高。在任何情况下,您寻找的答案可能是“因为属性作为一个整体继承”。@goodUser Javascript类继承是bas