In the book “WebGL – Up and Running” a custom geometry is constructed, in a very undramatic way. However, the second to last line of code raised my eyebrows. The code is as follows:
Saturn.Rings = function ( innerRadius, outerRadius, nSegments ) {
THREE.Geometry.call( this );
var outerRadius = outerRadius || 1,
...snip snip snip...
this.computeCentroids();
this.computeFaceNormals();
this.boundinSphere = { radius: outerRadius };
};
Saturn.Rings.prototype = new THREE.Geometry();
Saturn.Rings.prototype.constructor = Saturn.Rings;
My question is: why does he use a constructor instance in the prototype chain? Why can’t Saturn.Rings.prototype just be a new blank object that inherits from THREE.Geometry.prototype? Shouldn’t all stuff worth inheriting be positioned in THREE.Geometry.prototype? Why does he make the prototype an instance of the Geometry-constructor? (I am aware that the prototype chain is still correct, as the new prototype gets to inherit from THREE.Geometry‘s prototype).
Also, in the second line in the code above, instances of Saturn.Rings are put through the THREE.Geometry constructor. Thus, they get all they could dream of from THREE.Geometry construction process. Thus, there is no need to do the same to their prototype.
Lets take a look at how a similar geometry is handled in three.js itself:
THREE.CubeGeometry = function ( width, height, depth, segmentsWidth, segmentsHeight, segmentsDepth, materials, sides ) {
THREE.Geometry.call( this );
...snip snip snip...
}
this.computeCentroids();
this.mergeVertices();
};
THREE.CubeGeometry.prototype = Object.create( THREE.Geometry.prototype );
Way neater. The only problem is that he forgets to set the prototype’s ‘constructor’-property to point back to THREE.CubeGeometry, but that’s another matter.
Calling the constructor is probably done for compatibility.
Object.create()is a relatively new addition to JavaScript and is unsupported by some browsers released prior to the publication of ECMAScript 5 (such as IE8 and IE7). Just calling the constructor of another object is not enough for the object to inherit the other object’s prototype (demo). Certainly there are benefits to avoiding invoking the parent object’s constructor, but whetherObject.create()is “Way neater” is debatable.