Reputation: 3525
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
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
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