I'm building a composite for request
module, however I'm not sure what's the best practice regarding building objects in JS for Node.
Option 1:
function RequestComposite(request) { return { get: function (url) { return request.get(url); } } } var comp = RequestComposite(request);
Option 2:
function RequestComposite(request) { this.request = request; } RequestComposite.prototype.get = function (url) { return this.request.get(url); }; var comp = new RequestComposite(request);
Option 3:
var RequestComposite = { init: function (request) { this.request = request; }, get: function (url) { return request.get(url); } } var comp = Object.create(RequestComposite).init(request);
I tried to find my way around, however I got even more confused about how should I use objects...
Would the answer be different if I want to use objects for browsers?
Thanks.
Using an Object Literal This is the easiest way to create a JavaScript Object. Using an object literal, you both define and create an object in one statement. An object literal is a list of name:value pairs (like age:50) inside curly braces {}.
Objects can be created with new Object constructor. Attributes are then dynamically added using dot operator. let person = new Object(); person. firstName = "John"; person.
The most efficient way is the following:
Put all the essential initialisation in the constructor (e.g. validate constructor parameters, set properties, etc).
Set methods in the .prototype
property of the constructor. Why? Because this prevents from re-writing each method each time you create an object. This way you recycle the same prototype for each object you create. Efficient in memory and sparing coding time.
Do not use closures for private properties. Why? It is slow, and prevents you from using this object in an inheritance chain (the pseudo-private vars don't belong to the object, they're just accessible). It is instead common practice to use an underscore when declaring an object property, to indicate it is a _private property that should not be accessed from outside.
Use new
instead of Object.create
. It's easier to remember if you are used to other OOP languages; and at the end new
uses Object.create
under the hood.
In other words, something like this:
var Person = function (name) { this._name = name; }; Person.prototype.sayHello = function () { alert('My name is: ' + this._name); }; var john = new Person('John'); john.sayHello();
Some extra information:
Object.create vs new. Benchmark here. Although the question is for Node.js, I think the same behaviour is to be expected. (any correction is welcome)
Closures to emulate private properties: You can read about in this question.. The point that the private/closure properties do not belong to the object is a programming fact: they are accessible by the object methods but do not belong to the object. When using inheritance, that is a big mess. Besides, only methods that are declared in the constructor have access to the closure. Methods defined in the prototype do not.
Defining methods in the constructor or the prototype property: read this question, and take a look of this benchmark
The points I made here three years ago are still right from a performance point of view, but my opinion about what is the "recommended way" has changed a little in the meanwhile. Factory functions are in general a good option, which would be the OP's first approach. Just an example:
function Person(name) { return { sayHello: function () { alert('My name is: ' + name); } }; }
and then just do:
var p = Person('John');
In this case you trade flexibility (no new
coupling, ease of composition with other "mix-ins") and simplicity (no this
mess, easy object instantiation) for some speed and memory. In general they are perfectly valid. If you have performance issues, and those are because of this way of creating objects, revert to another method. The Object.create
approach is also good, falling somehow in the middle of new
and factory functions (side note: the new class
syntax is syntactic sugar for new
+ prototype
)
Summing up: my recommended way is starting from the simplest and easiest way of creating objects (factory functions) and then fall to other methods when you hit performance issues (which in most of cases is never).
There are many ways to create "Class" and "Object" in JS. I prefer this way:
var MyObject = function(args) { // Private var help = "/php/index.php?method=getHelp"; var schedule = "/php/index.php?method=getSchedules"; var ajax = function(url, callback, type) { //.... } // Public this.property = 0; this.getInfo = function() { // ... } // Constructor function(data) { this.property = data; }(args); }; var o = new MyObject();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With