0

I am wondering why when I console.log(Triangle.prototype), it just displays {} instead of displaying the the actual constructor function along with its properties side1 side2 etc When I console.log(Triangle.prototype.constructor) it will show function constructor. Also what does doing Triangle.prototype.constructor = Triangle do? Why am I setting the Triangle constructor into the Triangle constructor again. And when I do, Triangle.prototype = new Shape(), I am doing inheritance by inheriting Shape() properties correct? And doing Triangle.prototype.constructor = new Shape() will actually over ride the original Triangle constructor itself?

var Shape = function(){
    this.type = '';
}

Shape.prototype.get_type = function(){
    return this.constructor;
}

var Triangle = function(s1, s2, s3){
    this.s1 = s1;
    this.s2 = s2;
    this.s3 = s3;
}


Triangle.prototype = new Shape();

Triangle.prototype.constructor = Triangle;

module.exports = Triangle;
H. Lee
  • 67
  • 1
  • 9
  • Maybe start here: http://shop.oreilly.com/product/9780596805531.do – Jason Cust Dec 10 '16 at 05:20
  • `Triangle` is the function and `Triangle.prototype` is the parent object. `console.log(Triangle.prototype.constructor)` is logging the `Triangle` function. [Why am I setting the Triangle constructor into the Triangle constructor again?](http://stackoverflow.com/questions/20645466/resetting-the-constructor-property-of-prototype-object) – Sen Jacob Dec 10 '16 at 05:36
  • You should read [Benefits of using `Object.create` for inheritance](http://stackoverflow.com/q/17392857/218196) and [Why is it necessary to set the prototype constructor?](http://stackoverflow.com/q/8453887/218196) – Felix Kling Dec 10 '16 at 07:57

1 Answers1

0

In your example code, they explicitly set the constructor because it's what the cool kids do. This allows one to determine what "kind" of entity one may be working with.

var kid = new Bob();
console.log( kid == instanceof Bob ); // -> true

So by explicitly setting the constructor, you can change it to something else. But it doesn't affect anything other than pointing the "constructor" property to another function.

More Info

The constructor is not very useful, but it's been written into the language. In newer version of Javascript (e.g. ES6-7), they're starting to do more with it.

Don't worry yourself about "constructor" when you see it in code. The "constructor" is just a pointless property that points to the main function.

Changing the "constructor" property doesn't alter the prototype or affect anything.

The function itself is just known as a constructor. So perhaps this why the authors of the Javascript language included the property, so compilers/JavaScript Engines can determine which function is the constructor function.

Confusing? yes.

This example shows that the "constructor" property is just like any other variable that points to a funciton.

var Bob = function(){
    // This function is known as a "constructor".
}

var sameAsConstructor = Bob;

var areTheySame = Bob.prototype.constructor == sameAsConstructor;
console.log ( areTheySame ); // areTheySame = "true"

Proof

Here's an example, proving that nothing changes other than the "constructor" property.

// ---------------------------------------
// A "base class"
// ---------------------------------------
var Shape = function(arg){
    this.name = arg; 
}
Shape.prototype.seeSize = function(){
    console.log("Shape.prototype.seeSize", this.size);
}
Shape.prototype.seeName = function(){
    console.log("Shape.prototype.seeName", this.name);
}

// ---------------------------------------
// Let's set up another one and try to extend 
// our "base class" using the "constructor"
// ---------------------------------------
var Circle = function(arg){
    this.size = arg; 
}

// Now let's try setting the constructor
// ... in an effort to "try" and leverage
// the Shape function.

Circle.prototype.constructor = Shape;

You might think that the Circle function will now be replaced with the Shape function?

Nope.

As a test, we'll make an instance of a new Circle and then see what exactly gets "set" with our argument:

var sally = new Circle("bob");

Try and access the methods?

try {
    sally.seeSize();
} catch(e) {
    console.log("tried seeSize", e);
}

try {
    sally.seeName();
} catch(e) {
    console.log("tried seeName", e);
}

Nope.

Both "try's" above fail.

Again...

The prototype has nothing to do with the "constructor" property. Prototype is a completely different animal.

Now let's see that actually got "set" with our arg. Here we can see that "size" got set, just like what was in the Shape function.

console.log("sally.size", sally.size); // size = "bob"

And here, if we assumed that by replacing the constructor the "name" would be set... nope.

console.log("sally.name", sally.name); // name = undefined

However, you will see that the constructor does in fact point to the Shape function... not the Circle function.

console.log("sally.constructor", sally.constructor);

So, yes, very confusing and purposeless.

And Finally

In your example code:

Triangle.prototype = new Shape();

This causes Triangle to pick up all the functions and properties defined on the Shape's prototype and apply them to Triangle. That way any instance of Triangle can use any of the methods within Shape as well.

They then "reset" the constructor to point to Triangle because when Triangle's prototype was set, it also picked up the Shape's "constructor" property.

So by resetting the "constructor" they're just ensuring that the "constructor" property points to the proper function.

bob
  • 7,539
  • 2
  • 46
  • 42
  • `instanceof` is not affected in any way by the `constructor` property. The `constructor` is only a helper property for JS authors, it's not used internally by JS itself. – Oriol Dec 10 '16 at 07:58