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.