0

I saw two different patterns and explanations. One from DailyJS and many others: Rectangle.prototype = new Shape();

and then there's Crockford's here which implies just Rectangle.prototype = Shape;

Now theory-wise, why you need to run the 'new'? it runs the constructor function, yes. it also assigns the Rectangle's prototype the Shape's prototype. but we should be able to do inheritance just with a simple assignment of the parent into the prototype.

I wondered if the reason is prototype chaining. it seems, that in case 1, it will create a prototype chain. Meaning, that the Rectangle prototype will have the Shape prototype. In the second case, the Rectangle's prototype will just have Shape's methods - but not Shape's prototype methods.

Is that right? many thanks for any thoughts.

Lior
  • 40,466
  • 12
  • 38
  • 40

1 Answers1

4

Crockford which implies just Rectangle.prototype = Shape;

I can't really see that.

Now theory-wise, why you need to run the 'new'? it runs the constructor function, yes.

Yet we actually don't need (want) that, we only need the inheritance from Shape.prototype

it also assigns the Rectangle's prototype the Shape's prototype.

Not really. new Shape creates a new object which inherits from Shape.prototype, that's what matters us. You've got that right.

In the second case, the Rectangle's prototype will just have Shape's methods - but not Shape's prototype methods.

Yes, that's correct. You should inherit from Shape.prototype - but via Object.create(Shape.prototype), not by creating an instance. See JavaScript inheritance: Object.create vs new or What is the reason [not] to use the 'new' keyword here?. This is what Crockford actually does - and even before Object.create was introduced by EcmaScript 5.1, he found a clever way to do that with his helper function

function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
}

which is now the common shim for Object.create in browsers that don't support it natively.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • thanks @Bergi. I can revert to use Object.create but wanted to understand the theory. – Lior Oct 26 '12 at 15:16
  • thanks much for the detailed explanation. I actually asked why would Crockford do F.prototype = o and not F.prototype = new o, which would (1) run the constructor and (b) copy o.prototype to F.prototype. From your explanation, I now understand the reason: he didnt want to 'instantiate' o (and to run its constructor). The tradeoff, by the way, seems that we kind of lose the whole 'new' keyword - object instantiation in our code should be done by this function (object(o)). also, in the debugger, we cant see the object type right - it will always be shown as 'F' – Lior Oct 29 '12 at 21:12
  • No, we still use the `new` keyword to create `Shape`s or `Rectangle`s. Yet we don't need it (and should avoid it) when setting up the inheritance chain. On the debugger: Not sure how it gets the type, but it might have to do with the inherited `constructor` property. You might overwrite it (`Rectangle.prototype.constructor = Rectangle`) or set it within the creation (`Object.create(Shape.prototype, {constructor: {value: Rectangle}})` in environments that support the second parameter to [Object.create](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create). – Bergi Oct 29 '12 at 22:15