JavaScript, a language known for its versatility in web development, offers various ways to create objects. As you embark on your coding journey, grasping object instantiation is crucial. This process allows you to create instances of objects that can have their own properties and methods, making it a fundamental concept in JavaScript programming.
What is Instantiation?
You've already instantiated some objects with an object initializer using object literal notation:
const person = {
name: "John",
age: 20,
};
This instantiates an object, but for many applications, this form of instantiation is not ideal. For example, if you want to create multiple objects with the same properties and methods, you would have to repeat the code above many times.
Factory Functions
A factory function is a function that returns an object. It is a blueprint for creating objects with pre-defined properties and methods. There are a few ways to write a factory function.
The following example shows a factory function that creates a Person object:
function createPerson(name, age) {
return {
name: name,
age: age,
printInfo: function () {
console.log(`My name is ${this.name}. I am ${this.age} years old.`);
},
};
}
The createPerson() factory function takes two parameters, name and age. It returns an object with the name and age properties.
You can also use the this keyword in the function expression to dynamically fill in the variables
You can use the createPerson() factory function to create an instance of the Person object:
let john = createPerson("John", 20);
console.log(john.name); // John
console.log(john.age); // 20
console.log(john); // { name: 'John', age: 20 }
john.printInfo(); // My name is John. I am 20 years old.
john.name = "Johnny";
john.printInfo(); // My name is Johnny. I am 20 years old.
The createPerson() factory function creates an instance of the Person object and assigns it to the john variable. You can change the name property of the john object by assigning a new value to it. The printInfo() method prints the updated values of the name and age properties.
The new Operator and Constructor Functions
While using some of the built-in objects in JavaScript, for example, the Date object, you'll find that instantiation needs to happen with the new operator. Here is an example of instantiating a Date object:
const birthday = new Date(3000, 10, 1);
In this example, you created a Date object representing November 1st (as months in JavaScript Date object are zero-indexed, where January is 0 and December is 11), year 3000. The new operator along with a call to Date() initializes the new object and returns a reference to it. This reference is stored in the birthday variable.
There are several native objects in JavaScript, like the Date object, which are designed to be instantiated using the new operator. When you use new with Date(), you create an instance of the Date object with a constructor function that represents a specific point in time.
Constructor Functions
A constructor function is a function that returns an object, similar to a factory function. However, it is more powerful than a basic factory function. You'll start to see why in the next few sections, however, you won't be able to cover all the intricacies of constructor functions in this lesson.
The following example shows a type of constructor function that creates a Person object:
function Person(name, age) {
this.name = name;
this.age = age;
this.printInfo = function () {
console.log(`My name is ${this.name}. I am ${this.age} years old.`);
};
}
The Person constructor function takes two parameters, name and age. It assigns the name and age parameters to the name and age properties of the object it creates.
Note that you don't need to explicitly create and return an object, this happens implicitly when you use the new operator with the Person() constructor function. In the Person constructor function, you also make use of the this keyword.
You can use the new operator to call the constructor function:
let john = new Person("John", 20);
console.log(john.name); // John
console.log(john.age); // 20
console.log(john); // Person { name: 'John', age: 20, printInfo: [Function: printInfo] }
john.printInfo(); // My name is John. I am 20 years old.
The new operator creates an instance of the Person object and assigns it to the john variable.
This is not the only type of constructor function you'll encounter in JavaScript, but it is the most basic form. You'll learn about other types of constructor functions in later lessons.
What is the Difference Between Factory Functions and Constructor Functions?
The main difference between factory functions and constructor functions is that constructor functions can make better use of the concept of prototypes, while it's more complex for factory functions to do the same.
With constructor functions, you can easily set up a prototype chain between objects. This allows you to create objects that inherit properties and methods from other objects. This in turn allows you to create objects that are more efficient, as they don't need to store the same properties and methods multiple times.
In JavaScript, every object has a prototype. A prototype is an object that is associated with every function and object by default in JavaScript. Every object inherits properties and methods from its prototype.
You'll learn more about the prototype chain in later lessons when you cover classes, inheritance and more advanced object oriented programming.
The Object.create() Method
There is a utility method that offers yet another way to instantiate objects which allows you to take advantage of the prototype chain. This method is called Object.create().
The Object.create() method creates a new object, using an existing object as the prototype of the newly created object.
Here is an example:
const person = {
name: null,
isHuman: false,
printIntroduction: function () {
console.log(`My name is ${this.name}. Am I human? ${this.isHuman}`);
},
};
const matt = Object.create(person);
matt.name = "Matthew";
matt.isHuman = true;
matt.printIntroduction(); // My name is Matthew. Am I human? true
In this example, you created a person object. The person object has two properties: isHuman and name. The printIntroduction() method prints the name and isHuman properties of the object.
Crucially, the .printIntroduction() method is not defined on the matt object, but on the person object. The matt object inherits the printIntroduction() method from the person object.
You can verify this by accessing the .__proto__ property on an object. This property returns the prototype of the object. In this case, the prototype of the matt object is the person object:
console.log(matt.__proto__ === person); // true
console.log(matt.printIntroduction === person.printIntroduction); // true
You've also verified that the .printIntroduction() method is the same as the one on the prototype object, person.
Summary: JavaScript Object Instantiation
You've covered different ways to create objects in JavaScript and you've learnt about how those methods differ.
- Object Literal Notation: Simple object creation using literals, suitable for individual objects but not efficient for multiple similar objects.
- Factory Functions: Functions returning objects, useful for creating multiple instances with similar properties and methods. An example is given with a
createPersonfunction. - Constructor Functions and the
newOperator: Constructor functions, used with thenewoperator, allow for more powerful object creation, particularly leveraging prototypes. An example with aPersonfunction is provided. - Differences Between Factory and Constructor Functions: Constructor functions are better for utilizing prototypes, enabling efficient inheritance and property/method sharing.
- The
Object.create()Method: This method creates new objects using an existing object as the prototype, allowing for inheritance and property/method sharing.