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 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 Object.create(employeeMethods)
, 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.
class Employee {
constructor(name, position) {
this.name = name;
this.position = position;
}
program() {
console.log(`${this.name} is programming!`);
}
}
const employeeDiego = new Employee('Diego', 'Software Engineer');
Photo by Lucas Benjamin on Unsplash
Top comments (0)