【问题标题】:Why does my child class not inherit properties from the parent in Javascript?为什么我的子类不从 Javascript 中的父类继承属性?
【发布时间】:2020-01-20 05:36:03
【问题描述】:

我正在尝试了解 Javascript 的原型继承模型,但似乎缺少一些东西。我创建了以下一组对象:

function Dog() {
  this.legs = 4;
  this.arms = 0;
}

Dog.prototype.describe = function() {
  console.log("Has " + this.legs + " legs and " + this.arms + " arms");
}

function Schnauzer(name) {
  Dog.call(this);
  this.name = name;
}

Schnauzer.prototype.describe = function() {
  console.log(this.name + " is a Schnauzer with a shaggy beard");
  Dog.prototype.describe(this);
}

var my_dog = new Schnauzer("Rupert");
my_dog.describe();

我的期望是这会输出:

Rupert is a Schnauzer with a shaggy beard
Has 4 legs and 0 arms

但这是我实际得到的:

Rupert is a Schnauzer with a shaggy beard
Has undefined legs and undefined arms

【问题讨论】:

  • 是否需要在Schnauzer 中创建new Dog?您不应该为此使用class 吗?
  • 您实际上并没有从Dog 继承Schnauzer。您需要设置Schnauzer.prototype = Object.create(Dog.prototype) 并将构造函数属性添加回来:Schnauzer.prototype.constructor = Schnauzer:MDN: Inheritance in JavaScript

标签: javascript inheritance prototype


【解决方案1】:

Dog.prototype.describe(this);

您正在使用Dog.prototype 的调用上下文(this 值)调用describe 方法,并将狗实例作为第一个参数传递。但是describe 不接受任何参数,它会尝试从this 获取属性。

改为使用Dog.prototype.describe.call(this);,以使用狗实例的this 值调用方法:

function Dog() {
  this.legs = 4;
  this.arms = 0;
}

Dog.prototype.describe = function() {
  console.log("Has " + this.legs + " legs and " + this.arms + " arms");
}

function Schnauzer(name) {
  Dog.call(this);
  this.name = name;
}

Schnauzer.prototype.describe = function() {
  console.log(this.name + " is a Schnauzer with a shaggy beard");
  Dog.prototype.describe.call(this);
}

var my_dog = new Schnauzer("Rupert");
my_dog.describe();

不过,这有点难看,因为您必须使用 .call 才能获得一个在正常情况下会在当前对象的原型链上更高的方法。如果可能,您可以考虑重新命名您的 Schnauzer.prototype.describe 方法,这样它就不会掩盖 Dog.prototype 方法:

function Dog() {
  this.legs = 4;
  this.arms = 0;
}

Dog.prototype.describe = function() {
  console.log("Has " + this.legs + " legs and " + this.arms + " arms");
}

function Schnauzer(name) {
  Dog.call(this);
  this.name = name;
}
Schnauzer.prototype = Object.create(Dog.prototype);

Schnauzer.prototype.describeSchnauzer = function() {
  console.log(this.name + " is a Schnauzer with a shaggy beard");
  this.describe();
}

var my_dog = new Schnauzer("Rupert");
my_dog.describeSchnauzer();

或者使用class语法和super

class Dog {
  legs = 4;
  arms = 0;
  describe() {
    console.log("Has " + this.legs + " legs and " + this.arms + " arms");
  }
}

class Schnauzer extends Dog {
  constructor(name) {
    super();
    this.name = name;
  }
  describe() {
    console.log(this.name + " is a Schnauzer with a shaggy beard");
    super.describe();
  }
}

var my_dog = new Schnauzer("Rupert");
my_dog.describe();

【讨论】:

  • 这里的第三个选项可能是最适用的。我知道类语法在 javascript 中相当新,这是否得到广泛支持?
  • 普通类语法是ES2015,绝大多数浏览器都支持,IE11不支持。但是为了使现代语法的代码与 IE11 兼容,答案总是use Babel 自动将您的语法转换为 ES5 - 这使您的源代码在该语言的最新和最好的版本中保持可读性,同时允许过时的浏览器理解你的生产代码。
猜你喜欢
  • 1970-01-01
  • 2015-09-02
  • 1970-01-01
  • 2012-05-03
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 2020-11-08
  • 1970-01-01
相关资源
最近更新 更多