Javascript Object Creation Patterns

JavaScript has a multitude of styles for creating objects. But despite the variety and how different the syntax for each may look, they’re more similar than you probably realize.

1. Object Literals

Is the simplest method of JavaScript object creation.

var o = {
  x: 42,
  y: 3.14,
  f: function() {},
  g: function() {}
};

Drawback 

If we need to create the same type of object in other places, then we’ll end up copy-pasting the object’s methods, data, and initialization.

"We need a way to create not just the one object, but a family of objects."

2. Factory Functions

Is the simplest way to create a family of objects that share the same structure, interface, and implementation. Rather than creating an object literal directly, instead we return an object literal from a function. This way, if we need to create the same type of object multiple times or in multiple places, we only need to invoke a function:

function thing() {
  return {
    x: 42,
    y: 3.14,
    f: function() {},
    g: function() {}
  };
}

var o = thing();

Drawback 

JavaScript object creation can cause memory bloat, because each object contains its own unique copy of each function.

"We want every object to share just one copy of its functions."

3. Prototype Chains

This gives us a built-in mechanism to share data across objects, called the prototype chain. When we access a property on an object, it can fulfill that request by delegating to some other object. We can use that and change our factory function so that each object it creates contains only the data unique to that particular object, and delegate all other property requests to a single, shared object:

thing.prototype.f = function() {};
thing.prototype.d = 2;
thing.prototype.y = 11;

function thing() {
   var o = Object.create(thing.prototype);
   o.x = 42;
   o.y = 3.14;
   return o;
}

var o = thing();
// Is there an 'x' own property on o? Yes, and its value is 42.
console.log("o.x= " + o.x); //42
// Is there a 'y' own property on o? Yes, and its value is a 3.14.
// The prototype also has a 'y' property, but it's not visited. 
console.log("o.y= " + o.y); // This is called Property Shadowing
// Is there a 'd' own property on o? No, check its prototype.
// Is there a 'd' own property on o.[[Prototype]]? Yes, its value is 2.
console.log("o.d= " + o.d);
// Is there a 'f' own property on o? No, check its prototype.
// Is there a 'f' own property on o.[[Prototype]]? Yes, its value is a function.
console.log("o.f= " + o.f);
// Is there a 'n' own property on o? No, check its prototype.
// Is there a 'n' own property on o.[[Prototype]]? No, check its prototype.
// o.[[Prototype]].[[Prototype]] is Object.prototype and there is no 'd' property by default, check its prototype.
// o.[[Prototype]].[[Prototype]].[[Prototype]] is null, stop searching,
// no property found, return undefined.
console.log(o.n); // undefined

Drawback

This is going to result in some repetition. The first and last lines of the thing function are going to be repeated almost verbatim in every such delegating-to-prototype factory function.

"We want to avoid repeated call to create a delegation-to-prototype factory function inside our thing function."

4. ES5 Classes

We can isolate the repetitive lines by moving them into their own function. This function would create an object that delegates to some other arbitrary function’s prototype, then invoke that function with the newly created object by using new keyword, and finally return the object:

let thing = function() {
   this.x = 42;
   this.y = 3.14;
}
thing.prototype.f = function() {};
thing.prototype.d = 2;
thing.prototype.y = 11;
var o = new thing();

We’ve now arrived at what we commonly call “ES5 classes”. They’re object creation functions that delegate shared data to a prototype object and rely on the new keyword to handle repetitive logic.

Drawback

It’s verbose and ugly, and implementing inheritance is even more verbose and ugly.

"We want more cleaner implementation"

5. ES6 Classes

A relatively recent addition to JavaScript is ES6 classes, which offer a significantly cleaner syntax for doing the same thing:

class Thing {
  constructor() {
    this.x = 42;
    this.y = 3.14;
  }

  f() {}
  g() {}
}

const o = new Thing();

Conclusion

All things considered, my preference for JavaScript object creation is to use the class syntax. It’s standard, it’s simple and clean, it’s fast, and it provides every feature that once upon a time only factories could deliver.

Thank for Jeff Mott who is mostly the main source of this content.

General Javascript Object Creations Patterns