Skip to content

Objects in JavaScript

So far, we’ve learned how arrays can store multiple values in a single variable. But what if we want to store different types of information together, and give each piece of information a label? That’s where Objects come in.

We’ve all seen an ID card before, right? Maybe it was your school student ID or an employee badge at work.

If you look closely, that single ID card contains multiple types of information such as your name, photo, ID number, department, and maybe even a barcode.

All of that data is organized neatly on a single card with each piece of information has a label and a value:

  • Name: John Doe
  • Age: 25
  • Department: Engineering
  • Employee ID: 1023

Now, imagine trying to store that same data in separate variables:

const name = "John Doe";
const age = 25;
const department = "Engineering";
const employeeID = 1023;

It works… but it’s messy and hard to manage when you have dozens of employees.

Wouldn’t it be better to put all of this information together in one place, just like on an ID card?

That’s exactly what an Object does in JavaScript. It groups related data together in one structure using key-value pairs.

In JavaScript, an Object is a non-primitive data type that let’s us store information in key-value pairs together in a single variable.

Let’s see an example about our Employee ID Card from Analogy:

const employee = {
  name: "John Doe",
  age: 25,
  department: "Engineering",
  employeeID: 1023,
};

In the above example, you can clearly see that we have a variable named employee and it’s value have been assigned inside curly braces {}. Inside these curly braces, we have multiple information of different data types arranged in a Key:value pairs separated by a comma.

Key Value Data Type
name John Doe String
age 25 Number
department Engineering String
employeeID 1023 Number

You can think of keys as labels and values as the data those labels hold. So, if you imagine your Employee ID Card, then the key name is like the printed label Name: on your card, and John Doe is the information written next to it.

Each piece of information is unique and easily accessible and that’s the beauty of Objects in JavaScript.

Now that we’ve created an Object, how do we actually get the values inside it?

Well, JavaScript gives us two simple ways to do that:

In Dot Notation, we simply write the Object’s variable name, followed by a dot . symbol and then the name of the key we want to access or get value of.

const employee = {
  name: "John Doe",
  age: 25,
  department: "Engineering",
};

console.log(employee.name); // Outputs "John Doe"
console.log(employee.department); // Outputs "Engineering"

In the above example, you can see that we have an object named employee and we can access the properties name and department by using employee.name and employee.department to get the values.

This is the most common and cleanest way to access properties.

In Bracket Notation, we access the property’s value in same way we used to get values from the Arrays. We use Variable Name followed by Brackets [] and inside the brackets, we write the Key inside double/single quotes.

const employee = {
  "full name": "John Doe",
  age: 25,
};

console.log(employee["full name"]); // Outputs "John Doe"

In the above example, you can see that we have an object named employee, however the property name that we want to access have spaces in it. Hence for this special case, we can use Bracket Notation to access the value of those properties from that Object.

We just saw how we can access the values of a property from an Object using Dot Notation and Bracket Notation. But if you notice, doesn’t it sound too tedious? 🤔

Like, do we really need to type employee.name, employee.age, or employee.department every single time just to access those values?

Well, luckily, the answer is No! There’s a much cleaner and modern approach and it’s called Object Destructuring.

Destructuring allows you to unpack values from objects (or arrays) into individual variables in a single, simple statement.

Let’s see an example:

const employee = {
  name: "John Doe",
  age: 25,
  department: "Engineering",
  country: "USA",
};

// Without Destructuring
console.log(employee.name); // John Doe
console.log(employee.age); // 25

// With Destructuring
const { name, age } = employee;
console.log(name); // John Doe
console.log(age); // 25

In the above example, you can see that we used curly brackets {} to destructure the variables name and age from the Object variable employee. Now we can use these variables directly in our code and no need to keep using that Dot Notation over and over again!

Phew! That would save a lot of time!

Sometimes, we don’t just want to access a single property but we want to see all the keys, all the values, or even both together.

Thankfully, JavaScript gives us three very handy built-in methods to do just that.

Let’s take the same employee object:

const employee = {
  name: "John Doe",
  age: 25,
  department: "Engineering",
  employeeID: 1023,
};

console.log(Object.keys(employee)); // Outputs ["name", "age", "department", "employeeID"]
console.log(Object.values(employee)); // Outputs ["John Doe", 25, "Engineering", 1023]
console.log(Object.entries(employee)); // Outputs (see next line):
// [
//   ["name", "John Doe"],
//   ["age", 25],
//   ["department", "Engineering"],
//   ["employeeID", 1023]
// ]
console.log(employee.hasOwnProperty("department")); // Outputs true
console.log(employee.hasOwnProperty("salary")); // Outputs false

In above example, we can see that:

  • The Object.keys() method returns an array of all keys (property names) inside an object. It’s like reading all the labels on your Employee ID card and not seeing the data itself, just the labels.
  • The Object.values() method returns an array of all the values inside an object. This one shows all the actual information printed next to the labels.
  • The Object.entries() method returns an array of key-value pairs. Each pair itself is stored as a small array inside the bigger one. This is like holding a list of “label → value” pairs for everything on your ID card.
  • The hasOwnProperty() method helps you check whether a specific key exists directly inside an object. It’s like asking Does this ID card actually have a field called ‘department’?

We can also loop through the Object.entries using the for...of loop.

for (const [key, value] of Object.entries(employee)) {
  console.log(`${key} : ${value}`);
}

So far, we have seen how to access values from an Object. What about updating an Object? Maybe Adding some properties, editing already existing ones or deleting some properties?

Well now let’s explore that!

Let’s take example of this object:

const coffee = { name: "Mocha" };

Now, in this coffee variable, I would like to add a price property as well. Can you think of some way to do that?

Well, it’s pretty easy! Just like we used Dot Notation to access the values from Object, we can also use it to add a new property to an Object.

const coffee = { name: "Mocha" };
coffee.price = 5.45;
console.log(coffee); // Outputs {name: 'Mocha', price: 5.45}

In the above example, we can see from output that property price has been added to an Object. We can add multiple types of properties in the Objects, even functions (will cover in next topic).

Here’s an example of function:

const coffee = { name: "Mocha" };
coffee.brew = function () {
  console.log(`${this.name} is brewing...`);
};
coffee.brew(); // Outputs "Mocha is brewing..."

Here:

  • We added a function brew to our coffee object.
  • The keyword this refers to the object itself (coffee), allowing access to its own properties.

Hence, this is how we can add more properties inside an Object.

Updating an existing property is just as easy as adding one. You simply use Dot Notation (or Bracket Notation) and assign a new value.

const coffee = {
  name: "Mocha",
  price: 5.45,
};

coffee.price = 6.25; // Update the existing price
coffee.size = "Medium"; // Add a completely new property

console.log(coffee); // Output: { name: "Mocha", price: 6.25, size: "Medium" }

In the above example, we can see that:

  • The price property was updated from 5.45 → 6.25.
  • A new property size was added since it didn’t exist before.

Hence, this is how we update properties inside an Object.

Now, suppose our coffee shop decides to stop showing the price on the menu (bad idea ☕😅), and we want to remove that property from the object.

We can use the delete keyword.

const coffee = {
  name: "Mocha",
  price: 5.45,
  size: "Medium",
};

delete coffee.price;
console.log(coffee); // Output: { name: "Mocha", size: "Medium" }

NOTE: While deleting properties is fine for small tasks, it’s not always ideal for performance-heavy applications. In those cases, developers often prefer to set the property value to null or undefined instead of deleting it completely.

Hence, this is how we delete properties from an Object.

Freezing and Sealing Objects in JavaScript

Section titled “Freezing and Sealing Objects in JavaScript”

So far, we’ve seen how to add, update, and delete properties in an object. But what if we don’t want our object to be changed anymore?

imagine this: You’re running a coffee shop ☕, and you’ve finalized the prices for your menu. You want to make sure no one accidentally changes them in the code.

That’s where Object.freeze() and Object.seal() come in handy.

When you freeze an object, it becomes completely immutable. In other words, you can’t add, update, or delete any property.

Let’s see an example:

const coffee = {
  name: "Espresso",
  price: 3.5,
};

// Freeze the object
Object.freeze(coffee);

coffee.price = 4.0; // Won’t work
coffee.size = "Small"; // Won’t be added
delete coffee.name; // Won’t be deleted

console.log(coffee); // Output: { name: "Espresso", price: 3.5 }

In above example, you can clearly see that no more changes are allowed to happen with our coffee variable. Hence now our Object is frozen into this state. This is great for those use-case where you don’t want to make any changes to an Object in future.

console.log(Object.isFrozen(coffee)); // true

You can use Object.isFrozen(variableName) to check whether an object is frozen or not.

Object.seal() is very similar to the Object.freeze() but not quite as strict. We can’t add or delete any properties but we can edit their values.

Let’s see an example:

const latte = {
  name: "Latte",
  price: 4.25,
};

Object.seal(latte);

latte.price = 4.5; // Works (updating existing property)
latte.size = "Medium"; // Doesn't work (can't add new)
delete latte.name; // Doesn't work (can't delete)

console.log(latte); // Output: { name: "Latte", price: 4.5 }

In above example, you can clearly see that no more property additions or deletions are allowed to happen with our coffee variable except modifying the existing ones. Hence now our Object is sealed into this state.

console.log(Object.isSealed(latte)); // true

You can use Object.isSealed(variableName) to check whether an object is sealed or not.

We have already seen, how we can create objects and add new properties in them. But you have seen that these properties can be modified or deleted. We can prevent this by seal or freeze operation.

But there’s another ways to add properties to an object, that provides much deeper control.

const secureArtifacts = { name: "Ruby Pendant" };

Object.defineProperty(secureArtifacts, "catelogId", {
  value: "001",
  writable: false,
  enumerable: false,
  configurable: false,
});

secureArtifacts.catelogId = "222"; // fails silently
console.log(secureArtifacts);

for (const [key, value] of Object.entries(secureArtifacts)) {
  console.log(`${key} : ${value}`); // name : Ruby Pendant
}

In the above example, we added a new property catelogId into the secureArtifacts object with the help of Object.defineProperty().

We can modify properties like:

  1. writeable (true|false): Whether the object’s property can be modified or not.
  2. enumerable (true|false): Whether the object’s property can iterated over or not.
  3. configurable (true|false): Whether the object’s property cant be Tweaked (changed, modified and deleted) or not.

Since, the writeable is set to false, when we manually try to change value of catelogId to 222, it fails silently without any error.

So, how would we know what is the configuration of a property in an object?

Well, it’s pretty simple. We have getOwnPropertyDescriptor().

const desc = Object.getOwnPropertyDescriptor(secureArtifacts, "catelogId");
/* output: {
  value: '001',
  writable: false,
  enumerable: false,
  configurable: false
}
*/

Objects are a core part of JavaScript that allow you to group related data together using key-value pairs, making your code organized and easy to manage. From storing simple user information to handling complex nested data, understanding how to access, update, delete, and protect object properties is essential.