为类继承直接分配.prototype

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

我们知道执行继承的经典方法是Teacher.prototype = Object.create(Person.prototype);,其中Teacher扩展了Person。但是,如果我直接分配,它似乎也可以工作。

Teacher.prototype = Person.prototype;

我可以这样做吗?现在Teacher也可以访问Person的所有原型方法。

javascript node.js class inheritance prototype
2个回答
2
投票

可以,但这意味着当您分配一个属性Teacher.prototype时,您将对Person.prototype进行突变,这可能是不希望的。

// Works:
function Person(name) {
  this.name = name;
}
Person.prototype.getName = function() {
  return this.name;
}
function Teacher(name) {
  Person.call(this, name);
}
Teacher.prototype = Object.create(Person.prototype);
Teacher.prototype.teaches = function() {
  return true;
}

const p = new Person('bob');
console.log(p.teaches()); // p.teaches is not a function, as expected and desired

比较

// Bad:
function Person(name) {
  this.name = name;
}
Person.prototype.getName = function() {
  return this.name;
}
function Teacher(name) {
  Person.call(this, name);
}
Teacher.prototype = Person.prototype;
Teacher.prototype.teaches = function() {
  return true;
}

const p = new Person('bob');
console.log(p.teaches()); // `true`... oops, but bob is not a Teacher, bob is just a Person

最好使用Object.create方法,以便Teacher.prototype至少是(至少是)一个可以随意变异的空对象,它具有一个指向Person.prototype内部原型

请记住,对于real代码(而不是为了弄清楚语言机制而将代码用于思想实验),可以通过使用class来避免很多此类麻烦和语法干扰和extends关键字:

class Person {
  constructor(name) {
    this.name = name;
  }
  getName() {
    return this.name;
  }
}
class Teacher extends Person {
  teaches() {
    return true;
  }
}
const p = new Person('bob');
console.log(p.teaches()); // p.teaches is not a function, as expected and desired

1
投票

有时,直接分配原型确实很有意义,即当您希望same对象以different的方式构造时-与Java中的重载构造函数类似。例如:

function Rectangle(w, h) {
    this.w = w;
    this.h = h;
}

Rectangle.prototype.area = function() {
    return this.w * this.h;
}

function RectangleFromCoords(x1, y1, x2, y2) {
    this.w = x2 - x1;
    this.h = y2 - y1;
}

RectangleFromCoords.prototype = Rectangle.prototype;

let a = new Rectangle(20, 10);
console.log(a instanceof Rectangle, a.area())

let b = new RectangleFromCoords(20, 25, 10, 15);
console.log(b instanceof Rectangle, b.area())

但是在您的示例中,由于“人”和“老师”显然是不同对象,因此Teacher.prototype = Person.prototype是错误的,因为它基本上说“每个老师都是一个人”(可以)和“每个人是老师”(不好)。

© www.soinside.com 2019 - 2024. All rights reserved.