为什么子类不继承Javascript中父类的属性?

问题描述 投票:0回答:1

我试图理解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
javascript inheritance prototype
1个回答
3
投票

使用

Dog.prototype.describe(this);

您正在使用describe的调用上下文(this值)调用Dog.prototype方法,并将dog实例作为第一个参数传递。但是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();
© www.soinside.com 2019 - 2024. All rights reserved.