On the surface, objects in JavaScript appear to be a simple concept. You just assign a variable to a pair of { } and then we just continue on.

However, there are a few more things than just a simple assignment. Here is a quick and concise guide to quickly help you deepen your knowledge and understanding of JavaScript objects.

The scope of this piece is geared towards creating a summarized roadmap to help you navigate the different topics surrounding JavaScript objects. It’s not a detailed guide — but a concise one, complete with a roadmap diagram.

Without further ado, here is a concise guide to JavaScript objects.

1. JavaScript Objects in a nutshell

There are a total of 8 data types in JavaScript and they are all primitive types except for objects.

Objects are special because they can contain more than one data type and works on a key and value system.

In JavaScript, an object looks something like this:

let cat = { name: "Tibbers", age: 5 }

Here’s a diagrammatic breakdown of the different parts of an object:

There are two ways to create an object in JavaScript. The first and most common way is to do so via direct assignment of { }

This is called a literal assignment.

The alternative way is to use new Object(). This is called an object constructor.

Using Object() will generate you an empty object and is equivalent of using a literal assignment. However, the major difference is that you can create your own custom object constructor and use it to initialize a ‘blueprint’ of what your object should look like by passing in the values.

For more on custom object constructors, skip over to section 5 below.

2. copying & references JavaScript objects

The major difference between primitive data types and objects is that an object is stored and copied by reference. This means that when you do things to your objects, you’re not directly interacting with the object itself.

Rather, you’re dealing with the reference, which then ferries itself off to the multitude of spaces where the actual part of the object is stored.

This is because the object’s size is indefinite while primitive types know exactly the maximum space it might need to store a particular variable. As a result, JavaScript splits the object’s values and uses the property key as a map to the value.

So when you copy an object, you are copying the reference and not the actual object itself.

Think of it this way, when you create a copy of a primitive, it creates a clone of the actual thing. This is because primitives store the actual value.

In contrast, when you copy an object, you’re just copying the reference. So when you try to change things, you are still changing the same single object rather than something that’s an actual copy.

Let’s take a look at the following code:

let cow = "Betsy";
let cat = { name: "Tibbers", age: 5 };let heffer = cow;

let lion = cat;

console.log(cow, heffer);
//will log Betsy Betsy

heffer = "Daisy";
console.log(cow, heffer);
//will log Betsy Daisy

console.log(cat.name, lion.name);
//will log Tibbers Tibbers

lion.name = "Rwar";
console.log(cat.name, lion.name);
//will log Rwar Rwar

To properly copy an object, you need to create an independent copy of the actual items the references are pointing to. One technique is through Object.assign()

Object.assign() has two parts to it — the destination assignment and property and value pair you want to clone over.

In code, it looks something like this:

let cat = { name: "Tibbers", age: 5 };let catClone = {};Object.assign(catClone, cat);catClone.name = "Tibbles";console.log(cat, catClone);

When it comes to Object.assign() , you can also assign more than one object to the new object. This lets you create a hybrid of both objects without needing to do any fancy code work.

For example:

let cat = { name: "Tibbers" };
let age = { years: 1, months: 2 }let catClone = {};Object.assign(catClone, cat, age);catClone.name = "Tibbles";console.log(cat, catClone);

catClone will end up with a clone of the properties set in age , in addition to the information from cat

3. garbage collection

Garbage collection deals with freeing up memory space for when variables are no longer required.

In JavaScript, memory management is automated and we don’t get to see or have to explicitly deal with any of it. However, there are still some rules to help us keep our memory utilization in check.

Unused memory space is evaluated based on the context of a particular variable — that is, how reachable a particular variable is.

When it comes to objects, unreachability is determined by the association chain. Isolated islands are considered unreachable.

Why?

Because in JavaScript, objects are built in a prototypical manner — which is basically like a spiderweb methodology that interlinks one object to another to form a chain of inheritance.

If you don’t quite understand what prototypes are, here is a throwback article I wrote about it to help you out.

In short, if the connections to that object are deleted or nullified, the object that’s sitting on an isolated island where it will no longer be consumed, that entire island will go to garbage collection. Why? Because it’s no longer needed.

4. methods & “this”

In JavaScript, objects are more than just flat structures to hold data. It can also hold methods — that is, functions inside objects.

It looks something like this:

let cat = { name: "Tibbers" };cat.meow = function(){ console.log("meow"); }cat.meow();

The above syntax structure is called writing a function expression. You can also attach pre-declared functions as an object method too.

Here’s how to write it:

let cat = { name: "Tibbers" };function meow(){ console.log("meow"); }cat.meow = meow;cat.meow();

And finally, you can just write your method right inside the object itself. This is called an object literal.

let cat = { 
name: "Tibbers",
meow: function(){console.log("meow");}
}cat.meow();

The this keyword lets you access information stored within the object.

For example:

let cat = { 
name: "Tibbers",
sayHi: function(){
console.log("hi " + this.name);
}
}cat.sayHi();

You can, in theory, access information stored within the object by referencing the outer variable and don’t have to use this.

For example:

let cat = { 
name: "Tibbers",
sayHi: function(){
console.log("hi " + cat.name);
}
}cat.sayHi();

However, this way of accessing data is prone to issues because if things get renamed, your code will start throwing errors because it’s a hard reference to the information.

For example:

let cat = { 
name: "Tibbers",
sayHi: function(){
console.log("hi " + cat.name);
}
}let Tibbers = cat; //new reference made
cat = null; //reference to cat object is now deleted.Tibbers.sayHi(); //will now throw error

The keyword this is not bound to any particular location in JavaScript and runs on the idea of context. That is, where is this getting called at any particular time.

For example:

let cat = { name: "Tibbers" }
let dog = { name: "Bingo" }function sayName(){
console.log("My name is " + this.name);
}//attaching function as object methods
cat.sayName = sayName;
dog.sayName = sayName;//context of 'this' is cat
cat.sayName();//context of 'this' is dog
dog.sayName();

5. constructor, operator “new”in JavaScript objects

Think of your constructor function as the original stamp that allows you to create many instances of an object.

It starts off as a function and then executed with the keyword new

This is what it looks like:

function Cat(name){
this.name = name;
}let tibbers = new Cat("Tibbers");
let bingo = new Cat("Bingo);console.log(tibbers.name);
console.log(bingo.name);

6. optional chaining ‘?’

This is a fairly new feature in JavaScript and isn’t widely supported yet so you’ll most likely need polyfills.

It’s basically the ability to chain object properties without it causing an error.

It looks something like this:

cat?.name?.initials

The evaluation of the chain will stop right before the first undefined or null

Rather than throwing an error and stopping the program in its tracks, it’ll just throw undefined instead. However, the original variable itself must exist — in our case based on the above, cat must exist for it to work.

7. object to primitive conversion

At some point, you might need your object to turn into a primitive variable type for whatever reason. Here’s a quick list of how JavaScript will automatically convert it based on the situation:

  • Boolean: object will evaluate to true or false. If it exists, it will always evaluate to true.
  • Number: only happens when it’s logical like Date objects
  • String: will convert to string based on the required output. For example, console.log() and alert() expect strings and numbers. Objects will evaluate to string outputs in these contexts.

Final words

And that’s basically it for this piece.

I hope the quick summary of concepts above helped uncover and smoothed out any sketchy ideas you might have about objects in JavaScript.

If you’re interested in my other JavaScript concept maps, I’ve also got another one detailing the foundational fundamentals of JavaScript.

I hope you’ve found this piece a good referencing resource and thank you for reading.

Image credit: Doodling objects and CATS! by Laura Reen

Comments

0 comments