0

I'm trying to use prototypal inheritance, but I'm having trouble.

This doesn't work

var Parent = function(){
}

var Child = function(){
    this.__proto__ = new Parent();
}

var child = new Child();

console.log(child instanceof Child) //logs false

But this does

var Parent = function(){
}

var Child = function(){

}
Child.prototype = new Parent();

var child = new Child();

console.log(child instanceof Child) // logs true

The only reason why I want the first option is so that I can leverage the parent's constructor. I'm guessing this is the problem, but I'm not that great at javascript. How do I make this work?

5
  • When you say this.__proto__ = new Parent() you're saying "Okay new object, stop being a Child and start being a Parent instead," so it's not surprising that the object is no longer and instance of Child. Commented Nov 27, 2013 at 15:47
  • @apsillers is that because of this? Why doesn't the second method do the same thing then? Is it because I am not in the scope of new Child when I set the prototype? Commented Nov 27, 2013 at 15:50
  • Ah, I understand your confusion now; I'll update my answer. Commented Nov 27, 2013 at 15:54
  • 1
    Hi Josh, it's a little late but maybe the following answer can give you a better understanding of prototype (shared members) and this (instance members): stackoverflow.com/a/16063711/1641941 Commented Nov 27, 2013 at 23:51
  • but this is actually Classical Inheritance not Prototypal Inheritance. Commented Mar 31, 2017 at 12:31

1 Answer 1

2

The better way to do this is to call the Parent constructor on this:

var Child = function(){
    Parent.call(this);
}

That way, the Parent constructor code runs with its this set to the this in the Child constructor, but you don't change the __prototype__ of this.

Your two examples do produce a child instance that is structurally the same. However, the main difference is that in your first example, Child.prototype != child.__proto__. Although it is true that Child.prototype and child.__proto__ are both objects with a __proto__ of Parent.prototype, they are not the exact same object, so instanceof fails.

You may also want to do Child.prototype = Object.create(Parent.prototype); so that Child instances have access to Parent's prototype method. (Currently you don't have any methods on Parent.prototype, but maybe you will someday.)

Sign up to request clarification or add additional context in comments.

7 Comments

It is entirely my intention to have common methods on the Parent or its prototype
Don't I need to set the result of Parent.call(this) to something on Child? And, does Child.prototype = Object.create(Parent.prototype); replace Child.prototype = new Parent();?
@JoshC. No, Parent.call(this) stands on its own, because it mutates this. The Parent constructor does things like this.foo = 5, so after Parent.call(this) completes, your this has a foo property.
@JoshC. Yes, you should do Child.prototype = Object.create(Parent.prototype); instead of Child.prototype = new Parent(); Here's an example of why: stackoverflow.com/a/20201556/710446. Basically, the Parent constructor might do things per-instance (like set a unique ID), and you don't want all your Child instances sharing a single instance ID.
@JoshC. Yes, that's the correct way to use call. You could also use apply to pass in an array of arguments, like Parent.apply(this, [arg1, arg2, arg3]). This is especially handy if you want to pass in all of Child's arguments to Parent, by doing Parent.call(this, arguments).
|

Your Answer

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.