OOP: From Pseudo-classical class instantiation to Class instantiation
By: Diego Villa
Tags: Programming, JavaScript, Object Oriented

In this post, we will discuss how we can create objects in JavaScript. We will explore the traditional approach using Pseudo-classical class instantiation and will end with Class instantiation introduced in ECMAScript 6.

Introduction to objects

Objects are key/value pairs to store information about an entity that we can to represent in our code. You can create an object using the curly braces {} , and you can add properties and methods using the dot notation.

let employee = {}; // Properties

employee.name = 'Diego';

employee.position = 'Software Engineer'; // Methods

employee.program = function () {

console.log(`${this.name} is programming!`);

}; employee.program(); // Result: Diego is programming!

Functional instantiation

To create multiple objects we can use a constructor function. A constructor function encapsulates an object creation and it allows you to create multiple instances of the same object structure.

Creating a constructor function to instantiate new objects follows the functional instantiation pattern.

function Employee(name, position) {

let employee = {};

employee.name = name;

employee.position = position; employee.program = function() {

console.log(`${this.name} is programming!`);

}; return employee;

} const employeeDiego = Employee('Diego', 'Software Engineer');

const employeeJuan = Employee('Juan', 'Sofware Architect');

Functional instantiation with shared methods

Every time that we are creating a new instance of the Employee object we are creating, in memory, something like this:

const employeeDiego = {

name: 'Diego',

position: 'Software Engineer',

program: [Function],

}; const employeeJuan = {

name: 'Juan',

position: 'Software Architect',

program: [Function],

};

We can observe that we are creating two objects that share the same functionality ( program ). If we are creating two objects we probably didn't see the memory impact, but if we are creating thousands of objects we are wasting memory to store every time the same functionality. To avoid this problem we can use functional instantiation with shared methods.

const employeeMethods = {

program: function() {

console.log(`${this.name} is programming!`);

}

}; function Employee(name, position) {

let employee = {};

employee.name = name;

employee.position = position;

employee.program = employeeMethods.program; return employee;

} const employeeDiego = Employee('Diego', 'Software Engineer');

const employeeJuan = Employee('Juan', 'Sofware Architect');

With this improvement we will be creating, in memory, something like this:

const employeeDiego = {

name: 'Diego',

position: 'Software Engineer',

program: [Function: program],

}; const employeeJuan = {

name: 'Juan',

position: 'Software Architect',

program: [Function: program],

};

In JS objects are passed as reference, so we only have created a single object that encapsulates the program function, and every instance of the Employee object access the same function in memory.

Object.create

We can improve our constructor function using Object.create .

const employeeMethods = {

program: function() {

console.log(`${this.name} is progamming`);

}

}; function Employee(name, position) {

let employee = Object.create(employeeMethods);

employee.name = name;

employee.position = position; return employee;

} const employeeDiego = Employee('Diego', 'Software Engineer');

const employeeJuan = Employee('Juan', 'Sofware Architect');

With this improvement, every time we create a new instance of the Employee object we will have, in memory, something like this:

const employeeDiego = {

name: 'Diego',

position: 'Software Engineer',

}; const employeeJuan = {

name: 'Juan',

position: 'Software Architect',

};

If the created objects don’t have the program method, how will it be possible to invoke it? Every time we invoke employee.program() will fail because the created object doesn't have that method. But we use, so every time we invoke the program method it will look it in the parent object ( employeeMethods ).

Prototypal instantiation

In JavaScript, every function has a prototype property that references an object. This property allows us to share methods across all instances of a function.

function Employee(name, position) {

let employee = Object.create(employeeMethods);

employee.name = name;

employee.position = position; return employee;

} console.log(Employee.prototype); // Employee {}

So, we can use the prototype property to share the program function across all instances instead of using a separate object .

function Employee(name, position) {

let employee = Object.create(Employee.prototype);

employee.name = name;

employee.position = position;

} Employee.prototype.program = function () {

console.log(`${this.name} is programming`);

}; const employeeDiego = Employee('Diego', 'Software Engineer');

With this improvement, every time we create a new instance of the Employee object we will have, in memory, something like this:

const employeeDiego = {

name: 'Diego',

position: 'Software Engineer',

};

And the Employee.prototype will look like:

{

program: [Function]

}

Pseudo-classical class instantiation

Currently, we are using the Object.create() function to create a new object based on the prototype of a parent object, and then we return that created object. With the new keyword, we can merge the Object.create() and return functionality. The created object is called this .

function Employee(name, position) {

this.name = name;

this.position = position;

} Employee.prototype.program = function () {

console.log(`${this.name} is programming`);

}; const employeeDiego = new Employee('Diego', 'Software Engineer');

This pattern is called pseudo-classical class instantiation. When we use the new keyword we are invoking the function constructor. If we don't add the new keyword, the function won't create the object and it will return undefined .

Class instantiation

With ECMAScript 6 a class keyword was added. The class keyword was introduced to create classes in popular OOP programming languages like Java, but it works as the pseudoclassical class instantiation.