Maria
Maria

Reputation: 3525

directly assign .prototype for class inheritance

We know the classic way to perform inheritance is Teacher.prototype = Object.create(Person.prototype);, where Teacher extends Person. However, if I do direct assignment, it seems to work too.

Teacher.prototype = Person.prototype;

Can I just do this? Now Teacher has access to all Person's prototype methods too.

Upvotes: 0

Views: 63

Answers (2)

CertainPerformance
CertainPerformance

Reputation: 370729

You can, but it'll mean that when you assign to a property of Teacher.prototype, you'll be mutating Person.prototype, which is probably not desirable.

// 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

Compare to

// 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

It's better to use the Object.create method so that Teacher.prototype is (initially, at least) an empty object, free to be mutated, which has an internal prototype pointing to Person.prototype.

Keep in mind that for real code (rather than code being used for a thought experiment for the sake of figuring out the language mechanics), you can avoid much of this hassle and syntax noise by using a class and the extends keyword:

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

Upvotes: 2

georg
georg

Reputation: 214959

Sometimes this direct assignment of prototypes does make sense, namely when you want the same object to be constructed in different ways - similarly to overloaded constructors in Java. For example:

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())

But in your example, since "Person" and "Teacher" are obviously different objects, Teacher.prototype = Person.prototype is wrong, because it basically says "every teacher is a person" (which is ok) AND "every person is a teacher" (not ok).

Upvotes: 1

Related Questions