0

I'm trying to understand javascript inheritance/prototypes.

I did this:

function Foo(par){
    this.prop= par;
    this.propTwo = par;
}
function Bar(par){
    this.p=par;
}
Bar.prototype = new Foo();

If I do:

var myBar = new Bar("value");

myBar.propTwo is undefined (I assume this because even If I overwrite the prototype,I'm explicitly using the Bar "construct function" << please correct me if I'm wrong in this assumption.

if I want that Bar inherit from Foo, how should I create an instance of Bar or rewrite the constructs function(s) to get the propTwo also defined/assigned when creating myBar object (notice the same argument passed is assigned to both props) ?

I'm not even sure if I'm doing something "good" here, so if I'm totally wrong it's okay say it, if can be fixed please don't hesitate in details.

Update: I have selected Ethan Brown's answer as the correct because of 1 min. of difference (nothing personal). Both explanation works well and use two different ways (actually the idea is the same, one use "apply" the other one "call").

Also Bergi's link/comment it turns out to be an extended answer/justification about why not using this approach:

What is the reason to use the 'new' keyword here?

Thanks for the answers/material.

Community
  • 1
  • 1
Allende
  • 1,480
  • 2
  • 22
  • 39
  • possible duplicate of [Correct javascript inheritance](http://stackoverflow.com/questions/10898786/correct-javascript-inheritance) – Bergi Feb 10 '14 at 19:24
  • 1
    This code as is will yield a reference error in the constructor of Bar: `prop` is undefined. Is that a typo? Should that be `this.p = par;`? – Ethan Brown Feb 10 '14 at 19:31
  • 1
    and you're executing `Foo()` with no param..so `this.prop` and `this.propTwo` will just be undefined... – sdabet Feb 10 '14 at 19:34
  • Typo for "this.p = par" , thanks, and for "Foo()" that's right for FooObjects that will cause to haved both fields undefined, but from where I learned it's not necesary to send the parameters to replace/rewrite the prototype,actually I don't what effect will cause. – Allende Feb 10 '14 at 20:27
  • 1
    [The effect of being wrong](http://stackoverflow.com/q/12592913/1048572), unfortunately. You don't really want to invoke it there. – Bergi Feb 10 '14 at 20:45
  • Your current problem seems to be fixed, for more info about prototype including re using Parent constructor, setting prototype, what prototype is, what `this` is, how to pass arguments to constructor functions that have an inheritance chain and more you can check out this answer: http://stackoverflow.com/a/16063711/1641941 – HMR Feb 11 '14 at 03:11

2 Answers2

2

If I understand your question correctly, you're wondering why prop and propTwo are not set in myBar when you've declared Bar to be a subclass of Foo.

The answer is that the constructor function does not automatically call the constructor of its prototype. I think what you probably want is this:

// parent class
function Foo(par){
    this.prop = par;
    this.propTwo = par;
}

// subclass
function Bar(par){
    Foo.call(this, par);  // invoke parent class constructor
    this.p = par;         // custom construction
}
Bar.prototype = new Foo()

As Bergi points out in the comments below, subclassing by setting the subclass's prototype to a new instance of the parent class is probably what you want: that makes all subtype instances inherit from an instance of the parent class, not the parent class's prototype. If you're looking to emulate classical inheritance, your best bet is to the use the Object.create method:

Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.constructor = Bar;

See the MDN documentation on Object.create for more information. You also might want to read the link Bergi mentioned, and this SO question.

Community
  • 1
  • 1
Ethan Brown
  • 26,892
  • 4
  • 80
  • 92
  • Please read on [why not to use `new` for setting up the prototype](http://stackoverflow.com/q/12592913/1048572) – Bergi Feb 10 '14 at 20:46
  • Yes, you're right, thanks, Bergi. I was just copying the OPs code without editorializing, but I'll update my answer. – Ethan Brown Feb 10 '14 at 22:06
  • 1
    You are right, I was trying an example about "classical inheritance", but the sample didn't show/mention about using apply/call and I got stucked there (until several minutes later they mention just what you answered/posted), the sample just showed something like what I posted and I got really confused, thanks for the explanation and information, will continue my way on js and the functiional inheritance :) – Allende Feb 11 '14 at 00:40
1

You need to call the Foo function in "context" (or scope) of Bar. The effect is like calling Foo as a parent constructor.

function Foo(par){
        this.prop= par;
        this.propTwo = par;
    }
function Bar(par){
        this.p=par;
        Foo.apply(this,arguments);
    }
Bar.prototype = new Foo();

var myBar = new Bar("value");

console.log(myBar);
gevik
  • 3,177
  • 4
  • 25
  • 28
  • 1
    Please read on [why not to use `new` for setting up the prototype](http://stackoverflow.com/q/12592913/1048572) – Bergi Feb 10 '14 at 20:46