Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering JavaScript Object-Oriented Programming

You're reading from   Mastering JavaScript Object-Oriented Programming Advanced patterns, faster techniques, higher quality code

Arrow left icon
Product type Paperback
Published in Jun 2016
Publisher Packt
ISBN-13 9781785889103
Length 292 pages
Edition 1st Edition
Languages
Arrow right icon
Toc

Table of Contents (13) Chapters Close

Preface 1. A Refresher of Objects FREE CHAPTER 2. Diving into OOP Principles 3. Working with Encapsulation and Information Hiding 4. Inheriting and Creating Mixins 5. Defining Contracts with Duck Typing 6. Advanced Object Creation 7. Presenting Data to the User 8. Data Binding 9. Asynchronous Programming and Promises 10. Organizing Code 11. SOLID Principles 12. Modern Application Architectures

Object constructors

The creation of an object, as we have seen in the examples, is quite straightforward using the literal notation. We do not have to define a class, but we directly create the object just when we need it, and hopefully we can change its structure during the execution of our script.

Suppose, we need multiple objects of the same type, for example more person objects, which share the same structure.

Using the literal notation, we will have to repeat the definition for each object that we want to create, which is essential to identify the single person but unnecessarily repetitive for constant members such as the methods. In other words, using the literal notation in the definition of the objects, we get a non reusable result. For example, if we want to create two person objects, we need to write the following code:

var johnSmith = {name: "John", 
                  surname: "Smith", 
                  address: { 
                    street: "13 Duncannon Street", 
                    city: "London", 
                    country: "United Kingdom" 
                  }, 
                  displayFullName = function() { 
                    return this.name + " " + this.surname; 
                  } 
                }; 
var marioRossi = {name: "Mario", 
                   surname: "Rossi", 
                   address: { 
                     street: "Piazza Colonna 370", 
                     city: "Roma", 
                     country: "Italy" 
                   }, 
                   displayFullName = function() { 
                     return this.name + " " + this.surname; 
                   } 
                 }; 

Therefore, in order to avoid defining from scratch objects that have the same structure, we can use a constructor—a JavaScript function invoked using the new operator. Let's see how to create a constructor for the person object with an example:

function Person() { 
  this.name = ""; 
  this.surname = ""; 
  this.address = ""; 
  this.email = ""; 
 
  this.displayFullName = function() {...}; 
 
} 

This function defines the properties of our object by assigning them to the this keyword and setting default values. Even if this constructor may seem useless since it assigns just empty strings to the properties, it defines a common structure to any object created by it. So, in order to create an object of type person, we will have to call the function by prefixing the new operator:

var johnSmith = new Person(); 
johnSmith.name = "John"; 
johnSmith.surname = "Smith"; 
 
var marioRossi = new Person(); 
marioRossi.name = "Mario"; 
marioRossi.surname = "Rossi"; 

In this way, when we want to create multiple objects with the same structure, we will limit ourselves to just set the specific values that distinguish one object from another.

As you can see, the name given to the constructor is capitalized. This is not a requirement for JavaScript, but a common convention that helps to distinguish regular functions from constructors.

In the definition of a constructor, we can expect the presence of parameters that can be used in the initialization of our object. For example, consider the following definition of the constructor of the person object:

function Person(name, surname) { 
  this.name = name; 
  this.surname = surname; 
  this.address = ""; 
  this.email = ""; 
  this.displayFullName = function() {...}; 
} 

It allows us to create and initialize an object by specifying values directly in the constructor call, as in the following example:

var johnSmith = new Persona("John", "Smith"); 
var marioRossi = new Persona("Mario", "Rossi"); 

It is very important to use the new operator while creating an object through a constructor. In fact, if we forget it, what we get is not the creation of an object, but the execution of the function, with unpredictable results. For example, suppose that we try to create a person object omitting the new operator:

var johnSmith = Person(); 

The value of the variable johnSmith will be undefined, since the function Person() returns no value. In addition, all the properties and methods defined within the body of the function will be assigned to the object represented by this keyword in the execution context of the function, as can be for example the global object window in a browser. This assignment could redefine the value of variables with the same name causing side effects that are difficult to predict and to debug.

We can reduce the risk of such oversights by resorting to the use of strict mode:

function Person() { 
  "use strict"; 
  ... 
} 

In strict mode, the value of the object represented by the this keyword is undefined during the execution of the function. This generates a runtime error while trying to access the property of an object that does not exist, thus avoiding unwanted invocations of the constructor.

Unfortunately, this approach is not sufficient when the constructor is defined inside a namespace:

var mankind = { 
  ... 
  Person: function(name, surname) { 
    'use strict'; 
    this.name = name; 
    this.surname = surname; 
    ... 
  } 
}; 
 
var johnSmith = mankind.Person("John", "Smith"); 

In this case, the this keyword represents the mankind object, so we will not have a runtime error that warns us of the incorrect use of the constructor, but the properties name and surname will be attached to the mankind object.

The Object() constructor

We have seen how the use of a constructor offers us a higher level of abstraction in the creation of objects. In this section, we explore a particular constructor provided to us by JavaScript—the Object() constructor.

This constructor allows us to create a generic object, as shown in the following example:

var person = new Object(); 
person.name = "John"; 
person.surname = "Smith"; 

Here, we use the new operator to create a new instance of an empty object and then we create properties by assigning values, as in the literal approach.

Actually, creating an object using the literal notation or creating it by means of the Object() constructor is the same thing. Every object created using the literal notation has Object() as its implicit constructor. We can realize it by accessing the constructor property that every object has the following:

var person = {}; 
console.log(person.constructor == Object);  //result: true 

The Object() constructor is also able to generate object instances from any JavaScript expression, as shown by the following code:

var number = new Object(12); 
var anotherNumber = new Object(3*2); 
var string = new Object("test"); 
var person = new Object({name: "John", surname: "Smith"}); 

Apart from the last statement, which is equivalent to the creation of an object via its literal representation, the first three statements create an object from a primitive data type, such as a number or string. The result is not just a numerical value or a string value, but built-in objects specialized in handling numeric values and strings.

We will return later in the book on the Object() constructor for use in advanced mode.

You have been reading a chapter from
Mastering JavaScript Object-Oriented Programming
Published in: Jun 2016
Publisher: Packt
ISBN-13: 9781785889103
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime