Mat
Mat

Reputation: 3

Stoyan Stefanov: JavaScript Patterns - "The Default Pattern"

In chapter 6 (Code Reuse Patterns) there is following example:

// the parent constructor
function Parent(name) {
    this.name = name || 'Adam';
}

// adding functionality to the prototype
Parent.prototype.say = function () {
    return this.name;
};

// empty child constructor
function Child(name) {}

// inheritance magic happens here
inherit(Child, Parent);

In section "Classical Pattern #1 — The Default Pattern" the implementation of the inherit() function is:

function inherit(C, P) {
    C.prototype = new P();
}

In the section "Drawbacks When Using Pattern #1" is the following example:

var s = new Child('Seth');
s.say(); // "Adam"

I don't understand the following author's explanation:

This is not what you’d expect. It’s possible for the child to pass parameters to the parent’s constructor, but then you have to do the inheritance every time you need a new child, which is inefficient, because you end up re-creating parent objects over and over.

How is it possible for the child to pass a parameter to the parent's constructor? And how is it possible to change the prototype of an child object after construction if not through the hidden prototype property? Could anyone please give me an example for that, what the author means?

Upvotes: 0

Views: 331

Answers (3)

HMR
HMR

Reputation: 39310

As Bergi pointed out you should not create an instance of Parent to set up prototype part of Child.

To deal with constructor parameters or passing parameters to a function chain that is under construction (code you have to maintain and applications that need new features in the future are always under construction) you can use one object to be used when passing arguments.

This is also helpful when you use a mediator/publish subscribe object and never know what function will be called after another is finished.

For an example see here under "Passing (constructor) arguments"

Upvotes: 1

GameAlchemist
GameAlchemist

Reputation: 19294

The proposed inheritance scheme is rotten.
The right way to inherit, even in the 'simple way' is :

// the parent constructor
function Parent(name) {
    this.name = name || 'Adam';
}

// adding functionality to the prototype
Parent.prototype.say = function () {
    return this.name;
};

// Child constructor
function Child(name) {
      Parent.apply(this, arguments);  // to call with exact same parameters.
     // or  .call(this, /* the parameters you want */ ) ;
}

Child.prototype = Object.create(Parent.prototype); 

Child.prototype.otherMethod = function() { /*...*/} ;

Note that calling new P() instead of doing Object.create(P.prototype) is completely stupid, especially since the constructor might not accept no arguments. In this case, your application might throw an exception just for the inheritance, when Object.create cannot fail...

Forget about the other comments also... Talking about inefficiency for one object creation per class (not per instance) is just irrelevant. (maybe forget about the book ? :-) )

Upvotes: 1

Bergi
Bergi

Reputation: 665030

you have to do the inheritance every time you need a new child, which is inefficient, because you end up re-creating parent objects over and over.

It's not inefficient, not further objects are created if done properly. Indeed, you will have to do explicit inheritance every time for passing parameters and invoking parent constructors.

function Child(name) {
    Parent.call(this, name); // apply the parent constructor on new instance
                             // to set up instance variables like `name`
}

// inheritance stuff happens here
Child.prototype = Object.create(Parent.prototype);

… which is no magic when you understand how the prototype chain works and what Object.create does.

Upvotes: 2

Related Questions