Working with Objects in Javascript
Objects form an important part of JavaScript and learning how to work with them becomes the most important skill in JS
We will cover three aspects of objects in this article.
- Object Literal Syntax
- Function Constructors and Prototype Properties
- Pass by reference v/s pass by value
Object Literals
An object in Javascript is a collection of {name:value}
pairs. Essentially, it is a collection of associations between a name (or key) and a value. The value can be a number, a string, an array, a function, or even another object. If the value is a function then it is known as a method.
Let’s take a look at a simple interview candidate object.
This representation of an object, enclosed within curly braces, is called object-literal syntax. Object literals follow the following syntax rules:
- Name is separated from value by a colon
- Name-value pairs are separated by commas
- No comma follows the last name-value pair
Let’s see how we can call our candidate object
//Invoke the call property of the candidate
candidate.call()
//Fetch the firstname property of the candidate
console.log(candidate['firstname'])
Function Constructors
The above syntax only creates a single object. In the real world, however, we often need a blueprint for creating multiple objects. That blueprint is similar to how a class constructor behaves in languages like Python, C++ and Java.
In a strikingly similar fashion JavaScript allows us to create objects by using a constructor function. Objects are created by calling the constructor function with the new
keyword. It is called a function constructor because it actually creates a new Function
object.
Let’s see how it works.
//Function Constructor
function Person(title, firstname, lastname){
//this points to the empty object
this.title = title;
this.firstname = firstname;
this.lastname = lastname;
//automatically returns
}
this
keyword automatically creates an empty object and points to it- The constructor returns the object pointed to by the
this
keyword automatically at the end of the code block.
Now, let’s create an object from this constructor.
//Creating a new object
var p1 = new Person('Mrs.','Tanka', 'Jahari');
console.log(p1);
//Properties of Function Constructor
console.log("Length - "+ Person.length + " | Name - "+ Person.name);
Prototype Properties
The Person
object just has string properties as of now. We might want it to have some additional functionality as well. For example, we might have a function called call which is used to announce the person’s name. We don’t want that function to be created whenever a new object is created. That is sheer wastage of memory.
Javascript provides a way to attach such properties to all objects born of the same constructor. When a function is created in JavaScript, the JavaScript engine adds a prototype
property to the function. All subsequent objects inherit from this prototype. So if we attach a property to this prototype all objects will inherit that property.
Let’s see that in action. We will be attaching a function called call to the prototype so that it is available to all objects.
//Prototype Property
Person.prototype.call = function(){
console.log(this.title + " " + this.firstname + " "+ this.lastname
+ " is requested to come inside");
};
//Invoke that property on the previously created person
p1.call();
Note that we did not assign call explicitly to our object p1.
All objects inherit from the prototype. So, it must be possible to check if the prototype attached to every object is the same or not. Let’s do that.
//Create a second object
var p2 = new Person('Mr.','Tanka', 'Jahari');
//Print to the console to check
console.log("Are prototypes same?");
console.log(p1.__proto__ === p2.__proto__);
Pass by reference or value?
In JavaScript any type of data that represents a single value, like a string or a number is called a primitive. And because an object is a collection of name-value pairs, a primitive is basically something that is not an object.
Now let’s compare primitives and objects on the basis of how they are passed to functions.
Pass By Value — When a primitive is passed to a function a copy is created
Pass By Reference — When an object is passed to a function no copy is created and a pointer to the original object is created
Let’s start with primitives first.
//Primitves
num1 = 1;
//Copy of num1 created
num2 = num1;
//Modify the copy
num2 = num2+1;
//Print
console.log("num1 value = ",num1);
console.log("num2 value = ",num2);
We can see that even after modifying num2, num1 remains the same. This clearly shows that num2 points to a different memory location and is a copy of num1. Thus primitives are passed by value.
Let’s look at objects now.
//Objects
obj1 = {num: 1};
//Points to obj1
obj2 = obj1;
//Modify obj2
obj2.num = 2;
//Print and check
console.log("Obj1 is now = ", obj1);
console.log("Obj2 is now = ", obj2);
We can see that Object 1 changes when we change Object 2. That means they are pointing to the same memory location and a copy is not created. Thus objects are passed by reference.
There are many other aspects related to object creation, inheritance and manipulation, but these simple concepts should help you get started with JavaScript objects.