I am trying to understand functions and modules in JavaScript better, specifically to understand the best way to create my own data types. I have the listing of 2 files below, Rectangle1.js and Rectangle2.js, and their sample output, which I have created to understand this better.
I’d like help from the community in helping me understand which of these (or which other way) is the best way to structure my code to create my own datatypes.
Rectangle1.js
function Rectangle(x,y,w,h) {
width = w;
height = h;
this.area1 = function() {
return width*height;
}
}
Rectangle.prototype.area2 = function() {
return width * height;
};
Rectangle.area3 = function() {
return width * height;
}
exports.Rectangle = Rectangle;
Rectangle2.js
var RECTANGLE = (function(my) {
function init(x,y,w,h) {
this.w = w;
this.h = h;
}
function area() {
return this.w * this.h;
}
my.init = init;
my.area = area;
return my;
})(RECTANGLE || {});
exports.RECTANGLE = RECTANGLE;
SAMPLE INTERACTION
var r2 = require('Rectangle2.js');
r2.RECTANGLE.init(1,2,3,4);
r2.RECTANGLE // ...can see the private properties
r2.RECTANGLE.area() // returns 12
var r1 = require('Rectangle1.js');
r1 // shows area3 in r1
var rect = new r1.Rectangle(1,2,3,4);
rect // shows area1 in rect
rect.area1() // visible in methods, spits out 12
rect.area2() // not visible in methods, spits out 12
r1.Rectangle.area3() // not visible in rect, spits out 12
The preferred way of structuring objects in javascript is closer to what you wrote in Rectangle1.js, though there are a few problems:
First, when accepting arguments in the
Rectangle(x,y,w,h)constructor function, you are not assigning them to instance variables, but rather to a somewhat unsafe global scope, which explains whyRectangle.area3()returns the same result. Thethiskeyword allows you to assign and access instance variables. Keeping everything else the same, you would rather need to define the constructor like this (note the use ofthis.) :Also, ideally, when you’re defining functions that would be reused identically across all instances of the same object, it’s a better practice to define them on
Rectangle.prototyperather than onthisin your constructor function. In the first case, only one Function object is created and is shared for all instances ofRectangle; in the latter, a new one is created for every instances ofRectangle.Structuring modules is fine the way you did it, given you’re targeting a javascript platform where you can organize code in CommonJS-like modules, like Node.js.