Most of the developers who get started with JavaScript can pick up objects quite easily. However, mastering them and understanding how they work takes time and effort.
JavaScript objects are everywhere (even arrays are objects) and you should understand it well. We will dive into JavaScript objects in this article from the very basics to more practical and advanced use cases.
JS Objects 101 – The Basics
An object in javascript is very similar to objects in other programming paradigms. JavaScript stores the defined object as a reference in the variables.
JavaScript objects look quite simple. The most popular method to create an object in JavaScript is by using the syntax as below:
const person = { name: 'John', age: 30, email: 'john@gmail.com' }
This syntax is called the object literal. So, now person is an object with three properties: name, age, and email.
We can get or set the properties/methods of an object using two different notations:
1. Dot Notation (.)
This notation is very popular and widely used in many programming languages. You can access any nested properties using this notation.
console.log('I am', person.name) //prints 'I am John'
2. Square Bracket Notation ([])
This notation is more powerful than the dot notation and has two prime advantages:
- Use of a string literal (containing spaces, special characters) in property names.
- Dynamic access to properties using a variable.
console.log('I am ', person['age'], ' years old') // prints 'I am 30 years old'
Whenever we need to update any properties or delete the old ones of an object, then we can do them on the fly.
// update the name property person.name = 'Robin' // delete the email property delete person.email // add a new 'country' property person.country = 'Canada'
If you try to access a property that does not exist, then JavaScript will return undefined. Also, you can update a property just by assigning a new value to the property. If the property does not exist beforehand, then a new one will be created.
This tells us that JavaScript objects are quite flexible. With this knowledge, let’s move to methods.
More about methods and ‘this’ pointer
Methods allow us to do more with objects. Objects can contain not only properties but also functions. These are known as methods.
Whenever you create a method using the function keyword, there is a special ‘this’ object or ‘this’ pointer. It refers to the current object where the method has been defined. Using ‘this’, you can access the object properties right inside the method.
const folder = { name: 'My folder', size: 10999, details: function () { console.log('Folder name: ', this.name, ', size: ', this.size) }, } // you can update previous or add new method too folder.details = function(){ // your new code... } // call or use a method like normal functions folder.details() // outputs Folder name: My folder, size: 10999
The same rules for accessing and removing properties apply to methods.
Wait! That’s not the end. There are many more concepts related to javascript objects. We have only seen its surface concepts. So, you need to be aware of a few important key points:
- There are 4 other methods other than literals for creating an object:
- Object.create()
- Constructor functions
- Object() constructor
- ES6 class syntax
- Object literals(which we discussed).
- In JavaScript terminology, we refer to properties as keys, and objects are also known as maps.
- There are some inbuilt objects like Date, Math, String, Integer in JavaScript. They offer very useful methods. One example is using Math.random() to generate random values.
- JavaScript does not support inheritance. However, there is an important concept of prototypes (that we discuss next) in javascript that achieves a similar feature.
‘Prototypes’ in JavaScript Objects – Simplified
This is a concept that you cannot simply skip and you are sure to encounter it multiple times when using javascript objects. Although, it is hard to grasp at first for beginners.
Prototypes are how javascript enables your objects to inherit properties of some other object. Therefore, it is very similar to inheritance as in other languages.
You can create a new object, say, a student, that inherits the properties of some other object (it’s called prototype), say person. Then the new student object will inherit all the properties of the person object.
The term prototype refers to just an object. Specifically, a prototype is an object that is being inherited by other objects. Please take a look at the example below to understand it properly.
const person = { name: 'Person', sayHello: function () { console.log('Hi I am ', this.name) }, } // create a new object with the person object as prototype const student = Object.create(person) // add new properties to student student.grade = 5 // override properties of prototype student.name = 'Mary' // student has access to all the properties from the prototype student.sayHello() // returns 'Hi I am Mary'
We have used the inbuilt Object.create() method in JavaScript that takes a prototype(parent object) as an argument and creates a new object with the prototype.
If you have looked at the example above carefully, you will see that we did not define the method, sayHello() in the child object(student). But it was still accessible as it was defined in its prototype chain.
Wait, what is a prototype chain?
Good question. If you create another object using Object.create() and pass the student object (which already has a prototype), then what is going to happen? There will be two prototypes chained one on top of another, very similar to multiple inheritance.
So, the chain of parent objects one on top of the other is called the prototype chain (it’s just a fancy term).
When you try to access a property of an object, JavaScript first looks if that property exists in the object. Otherwise, it moves up in the prototype chain. Also, if the property is not found in the prototype chain, then it returns undefined.
Practical Applications of Prototypes
const stringLiteral = 'hello' // string is automatically converted to a String object by JS // before calling .length console.log(stringLiteral.length)
If you create a string variable in javascript, you can use the .length property on it. How is that possible? The answer lies in prototypes.
First, the string literal is converted to a string object. Now, it has a prototype object with the property length. This is how you can access .length on a string variable and get its length.
There are other techniques to create prototypes, one of them is using the prototype property on constructor functions. That’s a lot to take in if you are new to it. It is worth understanding and helps you solve day to day problems in JavaScript.
Practical Solutions on using JavaScript objects
1. Listing out all properties/values of an object
This is common problem developers encounter when trying to loop or access object values. So, there is a global object in JavaScript which contains some useful properties.
One is Object.keys(obj), which returns an array of properties/keys of an object. Also, another useful method is Object.values(obj) that returns the array of values.
const person = { name: 'Danny', age: 39, } const keys = Object.keys(person) const values = Object.values(person) console.log(keys) // ['name', 'age'] console.log(values) // ['Danny', 39]
Since keys and values are arrays, you can use them to loop through the properties one by one.
2. The for… in loop
Instead of looping through an array by using for, while loops, you can directly loop through the properties of an object using a ‘for in’ loop. Each iteration receives the property name of the object.
We can determine the value of the property using the square bracket notation(can you recall that?). So, if ‘propertyname’ is the key, then we can write object[propertyname] to get its value.
const person = { name: 'Danny', age: 39, country: 'Canada', } for (let myprop in person) { /* my prop is the object key name you can use the square bracket notation to dynamically determine property name */ console.log(myprop, ':', person[myprop]) } /* returns name : Danny age : 39 country : Canada */
3. Creating an object copy/clone
You can only store the reference to an object in a variable and not the object itself. Therefore, trying to assign it to another variable will not copy/clone an object. It will instead be just another name for your same object.
To create a clone of an object we can either use the ES6 spread operator or Object.assign()
const person = { name: 'Danny', } const person2 = person // person and person2 are just refering to the same object in memory const person3 = Object.assign({}, person) // or using ES6 spread operator // const person3 = { ...person } person2.name = 'Mary' console.log(person.name) // Mary person3.name = 'Jake' console.log(person.name) // Mary console.log(person3.name) // Jake
Conclusion
Objects don’t end here. This is where your journey with JavaScript begins. Having fundamentals down is the first important step in writing a better code.
We have discussed the important aspects of JavaScript objects. Still, there are many more nitty-gritty things that you will discover in your learning journey. The more you use objects in your code, the more you will understand it.