Johan
Johan

Reputation: 35194

Setting prototypes inside function constructor

var a = function(){
    this.sayFoo = function(){
        console.log('foo');
    };
}

var b = function(){
    console.log(this.prototype); //undefined
    this.sayBar = function(){
        console.log('bar');
    };
}

b.prototype = new a();

var bInst = new b();

bInst.sayFoo();
bInst.sayBar();

console.log(b.prototype); //a {sayFoo: function}

http://jsfiddle.net/KbBny/1/

How do I add sayBar to the b prototype inside the function constructor?

Does b.prototype = new a(); overwrite the prototype, or merge b's with a's?

Upvotes: 2

Views: 3440

Answers (3)

brat
brat

Reputation: 584

prototype Sort of inside constructor

You could use a wrapping function. I believe they are called decoratorfunctions in Javascript. Where you set the prototype. And then when you use that decoratorfunction as a constructor, you wont have to set the prototype separately. It will so to speak be set inside a function that acts as a constructor.

function Human(name, lastname, age) {
  function _human(name, lastname, age) {
    this.name = name;
    this.lastname = lastname;
    this.age = age;
  }
  _human.prototype.sayName = function() {
    console.log(this.name + " " + this.lastname);
  }
  var temp = new _human(name, lastname, age);
  return temp;
}

Then you just do:

var person = new Human("John", "Doe", 25);
console.log(person);
person.sayName();

Upvotes: 0

flavian
flavian

Reputation: 28511

You are not using the correct inheritance pattern.

Use:

b.prototype = Object.create(a.prototype);

In your case you are performing a simple override, you are not correctly establishing inheritance. Object.create is ES5, but you could polyfill with this:

Object.create

if (!Object.create) {
    Object.create = function (o) {
        if (arguments.length > 1) {
            throw new Error('Object.create implementation only accepts the first parameter.');
        }
        function F() {}
        F.prototype = o;
        return new F();
    };
}

Accessing the prototype

You can't access the prototype inside the definition block. You have a this reference for that.

var b = function() {
    a.call(this);
    b.prototype.doSomething = function() {console.log("b");}; 
};
b.prototype = Object.create(a.prototype);

DEMO

Upvotes: 2

Bergi
Bergi

Reputation: 664538

Does b.prototype = new a(); overwrite the prototype, or merge b's with a's?

It does overwrite it with a new a instance; nothing is merged (for example you'd need to update the b.prototype.constructor property). That's why you do add all properties to b.prototype after this line. However, actually you don't want to create an instance, but just set up the prototype chain correctly:

b.prototype = Object.create(a.prototype);

How do I add sayBar to the b prototype inside the function constructor?

You should not add it to the prototype, as it is not a prototype (shared) method - it's instance-specific to every a instance (at least it should be, otherwise you would put it on a.prototype and then it gets covered by above line). To get the instance method on all b instances as well, you use

var b = function(){
    a.call(this); // invoke the `a` constructor on this instance
};

Upvotes: 1

Related Questions