1

This seems to be something that have been discussed by many. But unfortunately, I couldn't find an answer to my issue. Here is a piece of code on Javascript inheritance (from a book):

function Car() {
    var self = this;
    self.type = "Car"
    self.go = function() {
        console.log("Going...");
    };
};

Toyota = function() { console.log("Original called"); };
Toyota.prototype = new Car();
Toyota.prototype.constructor = function() {
    var self = this;
    self.type = "Toyota";
    self.go = function() {
        console.log("A Toyota car is going...");
    }
};
Toyota.prototype.isJapaneseCar = true;

function TestCar() {
    console.log("Toyota.prototype.constructor: " + Toyota.prototype.constructor);
    var t = new Toyota();
    console.log("t.constructor: " + t.constructor);
    console.log(t.type);
};

And the output in Firefox console:

Toyota.prototype.constructor: function () {
    var self = this;
    self.type = "Toyota";
    self.go = function () {
        console.log("A Toyota car is going...");
    };
    }
Original called
t.constructor: function () {
    var self = this;
    self.type = "Toyota";
    self.go = function () {
        console.log("A Toyota car is going...");
    };
    }
Car

From the output, it is shown that the new Toyota() call:

var t = new Toyota();

didn't invoke the Toyota.prototype.constructor function as expected, instead it still call the function defined in the first place:

Toyota = function() { console.log("Original called"); };

A post with high upvote count gave a fairly detailed explanation together with examples: it said "3. It executes the constructor function, using the new object whenever this is mentioned." Does the "constructor" mentioned refer to prototype.constructor? How are the following 3 lines related:

  1. Toyota = function() { console.log("Original called"); }
  2. Toyota.prototype.constructor = function() { ...
  3. var t = new Toyota();

[EDIT] What confuses me most is why the constructor (Toyota.prototype.constructor) is not invoked when I call new Toyota()?

Community
  • 1
  • 1
Jiaji Wu
  • 459
  • 3
  • 10
  • 1
    `Func.prototype.constructor` should simply point to `Func`. The constructor function in your case is `Toyota`. – Felix Kling May 06 '12 at 18:53

1 Answers1

2

The constructor property in prototype object contains a reference to the function that constructs instances of that type of object. Hope I'm not trying to confuse here.

For a string object you would see the constructor property referencing the String function (a.k.a constructor informally.)

console.log("".constructor); // would print function String() { [native code] }

which is why typically we would reassign the class (i.e., the function) constructor property to its own.

Toyota.prototype.constructor = Toyota;

var t = new Toyota();
console.log(t.constructor); // prints function Toyota() { /* definition */ }

Hope that answers your question.

g13n
  • 3,218
  • 2
  • 24
  • 19
  • What confuses me most is why the constructor (Toyota.prototype.constructor) is not invoked when I call new Toyota()? – Jiaji Wu May 06 '12 at 19:36
  • Let me clarify myself, the `constructor` property is not being used when instantiating new objects. If you need to, you need to use the `prototype` object to do so by saying `Toyota.prototype = new Honda();`. In which case it is a prototype chain and whenever you are creating a `Toyota` object you are given a `Honda` object. This is how inheritance is done in JavaScript. – g13n May 06 '12 at 20:12
  • First thanks to your answer and comment! One thing I'm still confused with: some function (in my example: `function() { console.log("Original called"); }`) still gets called when I call `new Toyota()`. Where is this function kept in `Toyota`? How can I 'override' it? And what does "the function that constructs instances of that type of object" (in your answer) mean? – Jiaji Wu May 07 '12 at 02:49
  • @JiajiWu a function [object] becomes "special" when you invoke it using the `new` operator. Special in the sense that you get instance object `this`. Just try invoking `Toyota()` without `new`, it is possible but anything you assign to `this` becomes global. Okay, coming to your question about overriding, yes, you can "redefine" `Toyota` by saying `function Toyota() { /* ... */ }` – g13n May 07 '12 at 03:34
  • Looks like the "constructor" that's invoked when I call `new Toyota()` is not the same as `Toyota.prototype.constructor`, and it can only be set internally when function **Toyota** is defined (correct me if I am wrong). Your first comment already answered the question, but since I am such a newbie in Javascript, I didn't realize that until now. Thanks! – Jiaji Wu May 07 '12 at 12:56
  • @JiajiWu yep you got it, they're not the same. – g13n May 07 '12 at 23:02