1

When I run the following script, I get the error that sub.hello is not a function. Why not? Sub's prototype is Base and Base has the function hello. Since Sub does not have the function hello, shouldn't its prototype then be checked for the function?

function Base() {
}
Base.prototype.hello = function() {
 alert("hello");
}
Sub.prototype = Base;
function Sub() {
 Base.call(this);
}
var sub = new Sub();
sub.hello();
asked Dec 9, 2014 at 17:44
0

2 Answers 2

2

A better way to do inheritance in JavaScript is to use the Object.create function:

function Base() {
}
Base.prototype.hello = function() {
 alert("hello");
}
function Sub() {
 Base.call(this);
}
Sub.prototype = Object.create(Base.prototype);
// Restore constructor property
Sub.prototype.constructor = Sub;
var sub = new Sub();
sub.hello();

See jsFiddle

For further reading, check the Mozilla reference

answered Dec 9, 2014 at 18:02
Sign up to request clarification or add additional context in comments.

5 Comments

Don't forget to set Sub.prototype.constructor = Sub; since you've overridden Sub's constructor with Base's constructor.
Yep it still runs, my concern targets cases wherein the constructor property provides useful, cases such as this .
@WouterHuysentruit, @ryeballar: Setting Sub.prototype to Object.create(Base.prototype) override's Sub's constructor with Base's? Also, why do we pass Base.prototype in Object.create() instead of Base?
@hendryau no it doesn't, see jsfiddle.net/5stg6hzy/1, but there is a corner case where code could rely on prototype.constructor for whatever reason, see link of ryeballer
@hendryau answer to your second question: because you only want to clone the Base's prototype. As calling the Base's constructor is handled in Sub's constructor.
1

The function must exist on the prototype, not on the prototype's prototype.

You've effectively done this:

Sub.prototype.prototype.hello = function () { }

So, instead of Base.prototype.hello, either use Base.hello:

function Base() { }
Base.hello = function() { alert("hello"); }
Sub.prototype = Base;
function Sub() {
 Base.call(this);
}
var sub = new Sub();
sub.hello();

Or make Sub.prototype and instance of Base:

function Base() { }
Base.prototype.hello = function() { alert("hello"); }
Sub.prototype = new Base;
function Sub() {
 Base.call(this);
}
var sub = new Sub();
sub.hello();

answered Dec 9, 2014 at 17:50

10 Comments

@WouterHuysentruit Downvote posts, not people. Don't be a jerk just because you are wrong and I pointed it out. This is in the rules of this site. I watched your reputation decrease by 1 in the exact instant that you deleted your answer and my received a downvote.
I downvote because you removed hello from Base's prototype. Don't be a smartass and show him the real way of inheriting in js
@WouterHuysentruit My post does show the "real" way of inheriting in JS.
@meagar You're first snippet is confusing, if you're trying to create an abstract class that cannot be instantiated then I think its better to create an Object with static methods that will be assigned to Sub's prototype.
Furthermore, the second snippet actually invokes the Base constructor as opposed to @WouterHuysentruit answer wherein using Object.create(Base.prototype) does not. There's nothing wrong with it, it just invokes the constructor unnecessarily.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.