javascript - 为什么无法访问父类的同名属性?

标签 javascript node.js

我在 Javascript 中有两个类 A 和 B,A 扩展了 B,并且它们在构造函数中都有一个同名的属性。

我试图从 B 类访问属性 name 的值,但在从 A 创建新对象时它被 A 的值替换。

class B {
  constructor(){
    this.name = "I AM B"
  }
  
  speakB(){
    return this.name
  }
}

class A extends B {
  constructor(){
    super()
    this.name = "I AM A"
  }
  
  speakA(){
    return this.speakB() + " and " + this.name;
  }
}

var b = new B();
console.log(b.speakB())   //I AM B

var a = new A();
console.log(a.speakA())   //I AM A and I AM A

正如预期的结果,我想要得到 I AM B 和 I AM A,但我得到了 I AM A 和 I AM A。我还尝试了 super.speakB() + "和 "+ this.name; 但没有成功。

声明类时我遗漏了什么吗?

最佳答案

当您使用派生类扩展一个类,然后实例化该派生类时,那里只有一个对象。无论代码位于哪个类,this.name 都引用该对象上的相同 this 和相同属性。

这里的关键是,基类和派生类都在一个对象上设置属性。因此,如果您使用相同的命名属性,则无论哪个基类或派生类设置它,它都将是相同的值。

这样想:

let obj = new A();
obj.name = "Bob";

只有一个对象具有一个 .name 属性。 A 和 B 的方法都操作同一个对象,因此在方法 A 和 B 中使用相同的属性名称将设置完全相同的属性。

当你这样做时:

 this.name = "I AM A".

在派生类中,您将覆盖父级 B 为 .name 属性设置的先前值。

It means that I cannot use the same property name for both classes?

正确,如果您打算让两个属性具有单独的值,则不正确。请注意,在很多情况下,派生类想要访问基类设置的属性,因此这也是一个功能。但是,如果您打算将两个属性的基类属性和派生属性分开,那么您必须为它们指定不同的名称。


一些人可能会感到困惑的一个原因是,通过 class 语法声明的方法对于每个类都是分开的。每个类都有自己的原型(prototype)对象,并且在链中搜索原型(prototype)来解析方法。这确实允许您专门调用基类方法,即使基类和派生类都定义了相同的命名方法。

但是,对于常规实例属性分配 this.x = "foo" 来说,情况并非如此,因为它们被分配给实例对象,而不是原型(prototype)对象。请记住,原型(prototype)在所有对象实例之间共享,因此您无法在原型(prototype)上存储实例状态。

关于javascript - 为什么无法访问父类的同名属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58615359/

相关文章:

javascript - winston js : Is it possible to have custom formatters for different transports?

node.js - NodeJs 需要 ('./file.js' )问题

javascript - setTimeout() 在忽略间隔的情况下重复调用函数

javascript - Angular 4专注于向下箭头上的元素并滚动

javascript - 如何使用 jQuery/javascript 传递值?

javascript - sql-developer如何通过java脚本获取表中某列的值

javascript - 打字动画中的奇怪行为

javascript - SailsJS V1 - 蓝图查询无法正常工作

javascript - 我是否正确地进行了 AES 256 加密和解密 Node.js?

javascript - 如何禁用 GridView 中的链接按钮