Note: If you are more familiar with OOP syntax, you can also use class
which is just syntactical sugar over existing prototype-based way.
Performance Comparison between 4 ways of creating object - with constructor (Chrome 61 - https://jsperf.com/create-object-ways)
Option A: Using return
(Fastest 3x)
Option B: Using {key:value}
(1.5x)
Option C: Using prototype
(1x) <- Base
Option D: Using class
(1.02x)
Option A seams to perform best. Note that some of the performance boost is because it avoids use of new
or object.create
. So just to have a fair trial, here is another test between method-only objects without constructor and properties.
Performance Comparison between 4 ways of creating methods-only object (Chrome 61 - https://jsperf.com/create-static-object-ways)
Option A: Using return
(3.2x)
Option B: Using {key:value}
(Fastest 3.3x)
Option C: Using prototype
(1.8x)
Option D: Using class
(1.9x)
Option B outperformed Option A a little. Also the bottleneck caused by object.create
was more then new
.
Best Practice
Option A (using return
) is best performing in both the scenarios. This way can get little messy if you have many methods and properties.
I prefer to divide constructor & properties in separate object using Option A and methods in another object using Option B. This approach does need to send an extra instance
reference in parameters but can be useful if you have multiple objects using same properties & constructor (Some OOP inheritance can also be achieved).
Example:
// Constructor & Properties Object (Using option A)
var UserData = function(request){
// Constructor
if ( request.name )
var name = request.name;
else
var name = 'Not Available';
if ( request.age )
var age = request.age;
else
var age = null;
// Return properties
return {
userName: name,
userAge: age
};
};
// Object methods (Using Option B)
var Adults = {
printName: function(instance){ // Read propery example
console.log( 'Mr. ' + instance.userName );
},
changeName: function(instance, newName){ // Write property example
instance.userName = newName;
},
foo: function(){
console.log( 'foo' );
}
};
// Object methods (Using Option B)
var Children = {
printName: function(instance){
console.log( 'Master ' + instance.userName );
},
bar: function(){
console.log( 'bar' );
}
}
// Initialize
var userData = UserData ( {name: 'Doe', age: 40} );
// Call methods
Adults.printName(userData); // Output 'Mr. Doe'
Children.printName(userData); // Output 'Master Doe'
Adults.foo(); // Output 'foo'
Children.bar(); // Output 'bar'
Adults.changeName(userData, 'John');
Adults.printName(userData); // Output 'Mr. John'