Objects are a core concept in JavaScript. When I started learning about Objects it seemed tome pretty straightforward, just pairs of keys and values they said.
It took me some time to realize that this topic is much more complicated than I had in mind. I then started learning from different sources, some were good, but I could never get “the big picture”.
In this post I have tried to create a comprehensive overview of objects in JS, not going too deep into any subject, but just deep enough to help you understand and feel comfortable to go and read further.
So, let’s start at the beginning.
A JavaScript object is just a collection of properties, each property is a pair of a key and a value.
You can access keys using dot notation(obj.a) or brackets notation (obj['a']).
Remember that you should use the brackets notation if your key is one of the following:
Not a valid JavaScript identifier (has space, dash, starts with a number...)
Is a variable
Objects in JS are created with a property called Prototype which is a very important subject to master.
Every object in JavaScript has an internal property called Prototype, in most browsers, you can access it as _proto_. Prototype is Javascript’s solution for inheritance, which allows sharing functionality without duplicating the code in memory. It does so by linking one object to another. Simply put, Prototype creates a reference from one object to another.
Prototype chain — Every time you look for a property in an object, JS will try to find it on the object, if it can’t, it will look inside the Prototype object. If the property is still missing, JS will go on looking in the Prototype of the linked object. This will continue until JS finds the relevant property or until the end of the prototype chain.
Let’s take an example:
var cons = function () { this.a = 1; this.b = 2; } varobj=newcons(); cons.prototype.b = 3; cons.prototype.c = 4;
cons is a constructor (just a function that can use the new operator). At line 5 we create the new object, a new instance of cons. when created, obj also gets a prototype property. Now we add properties (‘b’, ‘c’) to the prototype object of cons and let’s take a look at obj :
obj.a // 1 - nothing new here, obj.a is still 1. obj.c - there is no c property on obj! but just as we said earlier, JS will now look in obj Prototype and will come back with a 4. Now ask yourself what is the value of obj.b and what would be the value after we delete obj.b?
obj.b is 2. We did set a b property but on cons Prototype so when we check for obj.bwe still get 2. However, after we delete obj.b, JS can’t find b on obj anymore so it goes to its prototype and comes back with a 3.
I want to briefly show the different ways to create an object and talk some more about the prototype.
Object literal: var obj = {a: 1}; we have created an object with the following ptototype chain: obj ---» Object.prototype ---» null As you can guess object.prototype is the prototype of object and it is also the end of the prototype chain.
Object.create(): var newObj = Object.create(obj); newObj will have this ptototype chain: newObj ---» obj ---» Object.prototype ---» null
Constructor: As the example above, a constructor is just a JS function that allows us to use new operator to create instances of it.
class rectangle {
constructor (height,width) {
this.height = height;
this.width = width;
}
getArea() {
return this.height * this.width;
}
}
let square = new rectangle (2,2);
Square is an instance of rectangle constructor, so we can call square.getArea() //4, square.width and also all the functions it inherited from object.prototype.
Which way should you choose? If you plan to create several instances you better use ES6 / constructor method but if you plan to create a one time object you might want to choose object literal because it is probably the easiest.
Now that we know about prototype and are familiar with all the ways to create new objects we can move forward talking about one of the most confusing parts in objects:
In JavaScript objects are a reference type. When we create an object var obj = {a: 1}; the variable obj receives the location in memory of the object and not the value! This is extremely important to understand because it can cause a variety of errors. When we create another object var newObj = obj, we have actually created a pointer to the location in memory of the obj and not a totally new object.
This means that when we do newObj.a = 2 we actually change obj so obj.a is now 2 !
This is so bug prone that many companies are working with immutable objects, meaning you can not change the object you have created. Instead you have to create a new object (a copy of the original one) and change it. This is the way important libraries like Redux are working and it is one of the most important concepts in functional programming. You can read more about it here.
Equality: This also means that two objects are never equal, even if they have the exact same properties. This is because JS actually compares the location in memory of the objects and two objects can never be in the same memory cell.
var fruit = {name : 'apple' }; // Two distinct objects with the same properties are not equalvar fruitbear = {name: 'apple'}; fruit ===fruitbear; // return false // here fruit and fruitbear are pointing to same var fruit = {name: 'apple'}; objectvar fruitbear = fruit; fruit ===fruitbear; // return true
So by now, you might be thinking how can I compare objects or how should I manipulate objects immutable?
Let’s go over some possibilities:
We understand we better not mutate our objects, so we would like to create a copy of the relevant object and change its properties.
object.assign() to the rescue.
var obj={a:1,b:2};
var newObj=Object.assign({}, obj, {a:2}) // {a : 2, b : 2 }
If we want to change a property value of obj we can use object.assign to create a copy of obj and change it.
You can see how we first create an empty object, then copy the values of obj and later add our changes so eventually, we get a new updated object to use.
Please pay attention that this will not work for a deep copy. A deep copy is when we want to copy an object which has one object property or more:
const obj = {a : 1, b : { a : 1 } }; // b property is an object
Object.assign () copies property values, so when the property value is a reference to an object, it only copies that reference.
For deep copy, we have to copy recursively. We could create a function or simply use _.cloneDeep of Lodash.
One cool trick for working with objects is to stringify them. What we do here is to stringify both objects, and then compare the resulted strings:
JSON.stringify(obj1) === JSON.stringify(obj2)
This works because we now compare strings which is a reference done by value data type. The bad news is that it is not always going to work, mainly because object properties order is not guaranteed.
Another good solution is to use Lodash’s _.isEqual which is making a deep object comparison.
Before we finish, let us go over some object’s interview questions which will help us dive in some more and to practice what we have learned.
Try to think about an answer before going on reading the rest.
To find the answer we would need to iterate over the object properties one by one and to count them. There are number of ways to iterate over an object:
object:
for in: This method traverses all enumerable properties of an object and its prototype chain. Now that we (hopefully) know prototype we can easily realize that if we want to get only the object properties it might not be right to use for in.
Also worth mentioning:
As you can see, most of the above methods return an array, so you can leverage all of the methods available to JavaScript arrays.
One of this methods is array.length so we can simply write:
let objLength = Object.getOwnPropertyNames(obj).length;
JSON.stringify(myObj) === “{}” - we are using the stringify tool again, which allows us to easily check if the object is empty (comparing strings not objects)
!Object.keys(myobj).length // true - As we said before, converting object’s keys to array can bene fit us. Here we are taking advantage of the length property inherited from Array.prototype to check for the length of the keys array. In JS 0 is converted to false so when we add not ! we turn it to true while all other number will result in false.
We have been through a lot. I hope you now feel somewhat more comfortable creating and dealing with objects.
I wish you great luck exploring JavaScript objects. Have fun with it!
We are a leading niche digital & tech recruitment specialist for the North East of England. We Specialise in the acquisition of high-performing technology talent across a variety of IT sectors including Digital & Technology Software Development.
Our ultimate goal is to make a positive impact on every client and candidate we serve - from the initial call and introduction, right up to the final delivery, we want our clients and candidates to feel they have had a beneficial and productive experience.
If you’re looking to start your journey in sourcing talent or find your dream job, you’ll need a passionate, motivated team of experts to guide you. Check out our Jobs page for open vacancies. If interested, contact us or call 0191 620 0123 for a quick chat with our team.
Follow us on our blog, Facebook, LinkedIn, Twitter or Instagram to follow industry news, events, success stories and new blogs releases.
Back to Blog