Table of Contents
It’s been a long time since we discussed or practiced object-oriented JavaScript. The last reference to JavaScript and objects was, I guess, in JavaScript 101 series part11 and part12. For today, you are going to have some fun while learning or recalling your older knowledge and memories on the subject of object-oriented JavaScript and programming as general. We will start slowly by going through some theory and then switch to examples. So, if you are not familiar with object-oriented programming don’t worry, you will learn everything you need. You can also take a look at links to JavaScript 101 series.
What is object-oriented programming
Let’s begin with on easier note … What is an object-oriented programming? Object-oriented programming refers to using abstractions to create real world like models, known as Classes. Object-oriented programming uses techniques like polymorphism (same interface, but different implementation), inheritance (ability to inherit features from other objects), modularity, and encapsulation (one object do a specific tasks). Most of the programming languages that are currently popular offer support for object-oriented programming, also known as OOP. Examples can be JavaScript, Python, PHP, Ruby and so on.
To get your head around the concept of object-oriented programming, you can think about it as creating or designing code as a collection of various blocks or pieces of code working together. This may sound rational, but don’t forget that the common view of any program is a collection of functions often referred to as instructions you want the computer to execute. This is the biggest difference between traditional and object-oriented programming; that every object is capable to communicate–process and transfer input and output–with other objects. In this way, all the objects are independent and self-sufficient entities.
Why use object-oriented programming
The main reason to use object-oriented programming is its great flexibility and maintainability. Those two factors are the main power behind the popularity of object-oriented programming in large-scale engineering. The most important property of object-oriented code is simplicity and ease of understanding–you don’t need to have knowledge of all modules in the system. This is achieved through technique mentioned above, which is modularity. Using the technique of modularity you are minimizing the dependencies between different modules and avoid duplicating the code. Also, when you will want to change functionality of some module, you will have to change only that module, nothing else.
Getting started with object-oriented JavaScript
In JavaScript, you can create object in two ways. First one is called Constructor function. Second is known as Literal notation. Among the programmers, the more preferred choice is to use the literal notation. What distinguishes the constructor the most is that you have to define it as you would do with function, i.e. include function keywords before the name of object (constructor function). Next, every property and method you define inside starts with the this keyword. Literal notation does not. Another difference is that constructor use an equal sign “=” to assign values to properties and methods. Literal notation uses colon “:”.
The last difference between those two options is that in constructor function you can write semi-colons ‘;’ after every property and method declaration. On the other hand, doing this in literal notation will break the code and cause an error. In literal notation properties and method declaration are separated with a comma ‘,’. Remember this to avoid unnecessary headaches during debugging your code in the future. Below are examples of both, Constructor function and Literal notation.
JavaScript:
// Example of Constructor function
// Create new object called ConstructorExample
function ConstructorExample() {
this.name = "Constructor function";
this.useThis = true;
this.useSemicolon = true;
this.useEqualSign = true;
this.introduction = function() {
console.log("This is an example of " + this.name + ".");
};
this.description = function() {
if (this.useThis && this.useSemicolon && this.useEqualSign) {
console.log(this.name + " use 'this' keyword, semi-colons and equal sign.");
}
};
}
// Create new instance of ConstructorExample object
var constructorOne = new ConstructorExample();
constructorOne.introduction(); // This is an example of Constructor function.
constructorOne.description(); // Constructor function use 'this' keyword, semi-colons and equal sign.
// Example of Literal notation
// Creatw new object called LiteralExample
var LiteralExample = {
name: "Literal notation",
useThis: false,
useSemicolon: false,
useEqualSign: false,
introduction: function() {
console.log("This is an example of " + this.name + ".");
},
description: function() {
if(this.useThis && this.useSemicolon && this.useEqualSign) {
console.log(this.name + " use 'this' keyword, semi-colons and equal sign.");
} else {
console.log(this.name + " doesn't use 'this' keyword. It use colons instead of an equal sign.");
}
}
};
LiteralExample.introduction(); // This is an example of Literal notation.
LiteralExample.description(); // Literal notation doesn't use 'this' keyword. It use colons instead of an equal sign.
In the examples above notice that when we use the Constructor function, we have to create a new instance of ConstructorExample object (constructorOne on the last line) in order to use properties and methods defined in ConstructorExample. When we try to initialize the introduction method on ConstructorExample, we will end up with an error. In other words, the Constructor function has to be instantiated first. This can be reason why, in object-oriented JavaScript, you might prefer Literal notation over Constructor–you don’t have to create any instances of the object.
Instances and inheritance
The fact that constructor functions have to be instantiated also means that unless you make change in the original constructor, any change you made to the instance will not the constructor itself or other instances. Meanwhile, when you change something in object literal (literal notation) that change can have affect to the entire script.
Of the mentioned techniques of object-oriented programming is inheritance. Meaning, every property and method defined in object constructor (Constructor function) will be included and available to use in its instances as well. You could see this in the example above when we called the introduction and description methods on constructorOne. Even though we didn’t define those methods precisely for this instance, it inherited them from the object constructor. The same applies to every property in Constructor as well.
As I mentioned previously, when you change the instance of an object, like add new property or method, it will have no effect on the original Constructor from which was the instance created. Also, when you create another instance from the Constructor, there will be no trace of that change neither. Let’s take a look at an example.
JavaScript:
// Creating new Constructor function
function ConstructorOne() {
this.name = "Constructor function";
this.language = "JavaScript";
this.oop = true;
this.selfIntitialized = false;
}
// Create an instance of ConstructorOne object
var instanceOne = new ConstructorOne();
// Create another instance of ConstructorOne object
var instanceTwo = new ConstructorOne();
// Add new property to instanceOne
instanceOne.isInstance = true;
// Test the isInstance property
console.log(instanceOne.isInstance); // true
console.log(instanceTwo.isInstance); // undefined
// Add new property to ConstructorOne object
ConstructorOne.prototype.inheritable = true;
// Test the inheritable property
console.log(instanceOne.inheritable); // true
console.log(instanceTwo.inheritable); // true
As you can see since the property inheritable has been added to the original Constructor, i.e. the prototype, it is now available to every instance created from this Constructor.
Object-oriented JavaScript and Object.create()
For a long time, Constructor function and Literal notation was the only way to create objects in JavaScript. In ECMAScript5 specification, however, another method has been added to those two. Below, let’s try the Literal notation with Object.create() method to create couple more instances of the object literal.
JavaScript:
// Creating new object called exampleOne using Literal notation
var exampleOne = {
description: "This is an example of using Object.create() method.",
language: "JavaScript",
version: 5,
oop: true,
print: function() {
console.log(this.description);
}
};
// Create new instance of an exampleOne using create() method
var instanceOne = Object.create(exampleOne);
// test print() method on an instance
instanceOne.print(); // "This is an example of using Object.create() method."
The parameter used in create() method specifies which object we want to be the prototype of this instance. We can also add another optional parameter that will specify new properties we want the instance to have. For example …
JavaScript:
// creating new instance of exampleOne object and also adding two new properties
var instanceOne = Object.create(exampleOne, {
state: {
value: "new",
writeble: true
},
isInstance: {
value: true,
writable: false
}
});
console.log(instanceOne.state); // "new"
console.log(instanceOne.isInstance); // false
In this example, we are creating new instance of exampleOne object using the name of this object as a prototype parameter. Next, we are also defining new properties for the instance–state with value of “new” and isInstance with value of “true”. The “writable” key says if the value of property can be updated just by assigning a new value to it (true or false). In case you are interested in what are other keys you can use while defining new properties, you can take a look at MDN on defineProperties() method.
Closing thoughts on object-oriented JavaScript
With this we are closing for today. I hope that this post help you either to learn something new or to dust off your older knowledge. Because we were not talking much about the new Object.create() method introduced in ECMAScript5, for those of you wanting to learn more about it, head on to MDN where you can find more examples and further explanation. Anyway, for the rest of you … Thank you very much for your time and see you on Monday.
If you liked this article, please subscribe so you don't miss any future post.
If you'd like to support me and this blog, you can become a patron, or you can buy me a coffee 🙂