JavaScript is a very flexible programming language and often one problem can be solved in a few different ways. However, some ways are more appropriate and efficient for some problems than others. JavaScript is also an object-oriented programming language, which might be a bit puzzling when it comes to the creation of an object. Why?
Because JavaScript enables a developer to create an object in two ways – with a help of object literal notation or with object constructor notation aka constructor function. And this is what this article is all about – getting to know what object literal and object constructor notation are and most of what is the difference, and when to use each. Let’s take a peek at how each example of object creation looks like:
// object literal notation
var Child = {};
// object constructor notation
function Child() {};
With both object literal and object constructor notation, you have just created a JavaScript object called Child. However, there is a slight difference.
Object literals and singletons vs function constructor and multiple instances
If you create an object by using object literals, you are creating a singleton. From mathematics, we know that a singleton restricts the instantiation of a class to one “single” instance. And yes, this can be useful when exactly one object is needed to coordinate actions across the system. Because that one “single” instance means when you make a change to the object, that will affect that object across the entire script.
On the other hand, when you define an object with a function constructor, it allows you to have multiple instances of that object (by calling the constructor function with the
“new” keyword). Compared to singleton, having multiple instances means that if you change one instance, that change will not affect other instances.
Let’s go through through this theory about object literals and singletons vs function constructor and multiple instances with an example and let’s imagine we’re a creating babysitting agency and we want to keep track of children and some information related to them, such as children’s names, age, a list of allergies and their parent’s phone number.
//we can create a child object by using object literals
var child1 = {
name: 'Alex',
age: 6,
allergies: ['milk', 'peanuts'],
phoneNumber: '031366595',
};
//but for every child, we will have to create another object
var child2 = {
name: 'Ana',
age: 5,
allergies: [],
phoneNumber: '071455231',
};
//and another literal object
var child3 = {
name: 'Maxim',
age: 3,
allergies: ['strawberries'],
phoneNumber: '046987532',
};
Do you get the point? This creation of objects might get very repetitive very soon – as you can see these children have all the same attributes (name, age, a list of allergies, and their parent’s phone number) and by using object literals we have to manually type these attributes all over again. But JavaScript has a far more elegant solution than this – when having one object that has the same attributes, we can create a blueprint for that object. And that is what a constructor function is all about.
We will create the same children we created in the literal notation above. Because of the multiple instances, in object constructor notation we will include calling the constructor function with the “new” keyword.
function Child(name, age, allergies, phone) {
this.name = name;
this.age = age;
this.allergies = allergies;
this.phoneNumber = phone;
}
var child1 = new Child('Alex', 6, ['milk', 'peanuts'], '031366595');
var child2 = new Child('Ana', 5, [], '071455231');
var child3 = new Child('Maxim', 3, ['strawberries'], '046987532');
See? Much faster and much more elegant, don’t you think?
Methods and properties with object literal and constructor notation
Objects in JavaScript have methods and properties, and they can be built with both the literal notation or the constructor function. In both cases, we rely on the keyword ‘this’, which represents the object that ‘owns’ the code. or in other words – when a keyword ‘this’ is used on an object, the value of ‘this’ represents the object itself. Let’s take a look at both examples:
// literal notation
var child1 = {
age: 6,
printAge: function() {
console.log(this.age);
}
};
// constructor function
function Child() {
this.age = 6;
this.printAge = function() {
console.log(this.age);
};
};
Now, besides the syntax difference, which we presented above, these two objects are different in the way you can use them. For example, the object you created with literal notation is ready for use, but you must instantiate the object that you created with the constructor function.
// literal notation
child1.printAge();
// constructor function
var BabySittingChild = new Child();
BabySittingChild.printAge();
You can see in the example above that with the literal notation you can’t have a constructor and you can’t initialize your object. However, there is a way to get around this – you can add a custom init() function. On the other hand, the constructor function demands initialization and you can even pass additional parameters to the object through the built-in constructor, like that:
// constructor function
function Child(age, name) {
this.age = age;
this.name = name;
this.printInfo = function() {
console.log(this.age, this.name);
};
};
var child1 = new Child(6, 'Alex');
var child2 = new Child(5, 'Ana');
child1.printInfo(); // 6 Alex
child2.printInfo(); // 5 Ana
Literal notation object and singleton approach vs. object constructor notation and instantiation
We already explained some bits about literal notation object and singleton approach vs. constructor notation object and instantiation. To sum up again – the literal notation object and singleton approach are about working with an original object even if you define a new variable with the object as a value. The object constructor notation or the constructor function and instantiation are about instantiating how many objects you need, and they will be unique.
Literal notation vs. constructor function: what about privacy issues and public stuff?
Easy divination between literal notation vs. constructor function regarding privacy issues would be – objects created with literal notation are public while objects created with a constructor function can be made private, thanks to the concept of closure. By its nature, a JavaScript object literal does not provide private scope. Although a pain in the ass, creating private parts with the literal notation object is possible, and any of the members of an object literal can certainly be a function that is capable of private scope. The biggest advantage of object literal notations is that they allow you to create clean name-spaced code that is easy to pass around.
On the other hand, if a part of your code relies on privacy issues, you should create your objects with a constructor function. Thanks to the concept of closure, protecting the privacy of some members is much easier with the constructor function.
function Child() {
//private members
var name = 'Alex';
var privatePrintName = function() {
console.log(name);
};
//public members
this.printName = function () {
privatePrintName();
};
}
var child1 = new Child();
child1.printName(); // 'Alex'
child1.privatePrintName(); // TypeError: child1.privatePrintName is not a function
console.log(child1.name); // undefined
In conclusion, although we can create an object with either object literal and constructor, these two concepts differ in their inherent nature and features. It essentially boils down to the fact of what we need in our code. If you need multiple instances, go with a constructor, if not, go with the principle of singleton that is reserved for literals. If your code deals with privacy, go with the constructor function, if not, objects created with literal notation are the way to go.