JavaScript objects

JavaScript: Objects

In JavaScript, objects are one of the most important data types. They allow you to store collections of data in a structured way using key-value pairs, where each key (also known as a property) is a unique identifier, and the value can be any valid JavaScript data type, such as strings, numbers, arrays, or even other objects.

Objects are widely used to represent and manage real-world entities, such as people, products, or settings. For instance, an object might represent a person, with properties like name, age, and address.

Goal of this article: You will learn how to:

  • Create objects in JavaScript.
  • Access and modify object properties.
  • Work with object methods.
  • Handle complex objects, including nested objects and object destructuring.

By mastering objects, you’ll be able to organize and manipulate data efficiently in your JavaScript programs.

Table of Contents

Creating Objects

In JavaScript, there are two main ways to create objects: using object literal syntax and the new Object() constructor.

Using Object Literal Syntax {}

This is the most common and simplest way to create objects. You define an object by enclosing key-value pairs inside curly braces {}. Each key is followed by a colon : and the corresponding value.

const person = {
    name: "Edward",
    age: 30
};

In this example, person is an object with two properties: name (with the value "Edward") and age (with the value 30).

Using new Object()

You can also create an object using the new Object() constructor. This method is less common but still valid. After creating an empty object, you can assign properties to it manually.

const person = new Object();
person.name = "Edward";
person.age = 30;

Here, we create an empty object and then add properties (name and age) to it, assigning values afterward.

While the object literal syntax is more common and concise, both methods are valid ways to create objects in JavaScript.

Accessing Object Properties

In JavaScript, you can access the properties of an object in two primary ways: dot notation and bracket notation.

Using Dot Notation

Dot notation is the most straightforward way to access object properties. You simply use the object’s name followed by a period (.) and then the property name.

const person = {
    name: "Edward",
    age: 30
};

console.log(person.name); // Edward

Here, person.name accesses the name property of the person object, which returns "Edward".

Using Bracket Notation

Bracket notation is useful when the property name is stored in a variable or is not a valid identifier (e.g., contains spaces or special characters). You use square brackets ([]) and pass the property name as a string.

const person = {
    name: "Edward",
    age: 30
};

console.log(person["age"]); // 30

In this example, person["age"] accesses the age property of the person object and returns 30.

When to Use Bracket Notation:

  • When the property name is dynamic (e.g., stored in a variable).
  • When the property name is not a valid JavaScript identifier (e.g., contains spaces or starts with a number).

Example with Dynamic Key:

const person = {
    name: "Edward",
    age: 30
};

const key = "name";
console.log(person[key]); // Edward

Both dot and bracket notations are essential tools for accessing object properties in JavaScript. The choice of which to use depends on your specific use case.

Modifying Object Properties

In JavaScript, you can modify the properties of an object in a few simple ways: using dot notation or bracket notation.

Modifying Properties Using Dot Notation

Dot notation allows you to change the value of an object’s property by directly assigning a new value to it.

const person = {
    name: "Edward",
    age: 30
};

person.name = "Samantha"; // Modifying the 'name' property
console.log(person.name); // Samantha

In this example, we modify the name property of the person object from "Edward" to "Samantha". After the modification, person.name returns "Samantha".

Modifying Properties Using Bracket Notation

Bracket notation works similarly to dot notation but is more flexible, especially when dealing with dynamic or non-standard property names. You can modify an object’s property by assigning a new value to it using brackets.

const person = {
    name: "Edward",
    age: 30
};

person["age"] = 25; // Modifying the 'age' property
console.log(person.age); // 25

Here, we change the age property from 30 to 25 using bracket notation. The person["age"] syntax works just like dot notation, but it is especially useful when the property name is dynamic or not a valid JavaScript identifier.

Adding New Properties

In JavaScript, you can easily add new properties to an object using either dot notation or bracket notation. Here’s how to do it:

Adding New Properties Using Dot Notation

To add a new property to an object, simply assign a value to a new property using dot notation.

const person = {
    name: "Edward",
    age: 30
};

person.city = "Lusaka"; // Adding a new property 'city'
console.log(person.city); // Lusaka

In this example, we added a new property city to the person object and assigned it the value "Lusaka". After adding the property, we can access it using person.city.

Adding New Properties Using Bracket Notation

Bracket notation is particularly useful when the property name is dynamic or includes special characters (e.g., spaces, hyphens, or numbers).

const person = {
    name: "Edward",
    age: 30
};

person["country"] = "Zambia"; // Adding a new property 'country'
console.log(person.country); // Zambia

In this case, we used bracket notation to add a property country to the person object. We can then access it with person.country.

Deleting Properties

In JavaScript, you can remove properties from an object using the delete keyword. This can be useful when you no longer need certain properties or when cleaning up data.

To remove a property from an object, simply use the delete keyword followed by the property you want to remove.

const person = {
    name: "Edward",
    age: 30,
    city: "Lusaka"
};

delete person.city; // Remove the 'city' property
console.log(person.city); // undefined

In this example, we used delete person.city to remove the city property from the person object. After deleting it, trying to access person.city will return undefined because the property no longer exists.

Important Notes:

  • The delete keyword only removes properties from an object, not the entire object itself.
  • If the property does not exist, using delete will not cause an error but will simply return true and leave the object unchanged.

The delete keyword is an easy and straightforward way to remove properties from an object in JavaScript.

Checking if a Property Exists

In JavaScript, you often need to check if a property exists on an object. There are two common ways to do this: using the in operator and the hasOwnProperty() method.

Using the in Operator

The in operator checks if a property exists anywhere in the object’s prototype chain, meaning it will check not only the object itself but also any inherited properties.

const person = {
    name: "Edward",
    age: 30
};

console.log("name" in person); // true (property exists)
console.log("city" in person); // false (property does not exist)

In this example, "name" in person returns true because the person object has a name property. However, "city" in person returns false since the person object does not have a city property.

Using the hasOwnProperty() Method

The hasOwnProperty() method checks if a property exists only on the object itself, not on its prototype chain. This method is useful when you want to check if the object contains the property, not if it is inherited.

const person = {
    name: "Edward",
    age: 30
};

console.log(person.hasOwnProperty("name")); // true (property exists on the object itself)
console.log(person.hasOwnProperty("city")); // false (property does not exist on the object itself)

In this example, person.hasOwnProperty("name") returns true because name is a property directly on the person object. person.hasOwnProperty("city") returns false because the city property doesn’t exist on the person object.

Summary:

  • Use the in operator to check if a property exists anywhere in the object’s prototype chain.
  • Use hasOwnProperty() to check if a property exists directly on the object itself (not inherited).

These methods provide flexible ways to check for property existence, depending on whether or not you’re concerned with the object’s prototype chain.

Iterating Over Object Properties

When working with objects in JavaScript, you often need to iterate over the properties to access or manipulate their values. Here are several ways to loop through object properties:

Using the for...in Loop

The for...in loop is a traditional way to iterate over all enumerable properties of an object. This loop gives you access to each property name (key) in the object, which you can then use to access the corresponding value.

const person = {
    name: "Edward",
    age: 30,
    city: "Lusaka"
};

for (let key in person) {
    console.log(key, person[key]);
}

The for...in loop iterates over each key in the person object, and person[key] accesses the corresponding value.

Using Object.keys() for Property Names

Object.keys() returns an array of the object’s property names (keys). You can then use forEach() to iterate over the array of keys.

const person = {
    name: "Edward",
    age: 30,
    city: "Lusaka"
};

Object.keys(person).forEach(key => {
    console.log(key, person[key]);
});

Object.keys(person) returns an array of the keys, and forEach() iterates over them to print each key-value pair.

Using Object.values() for Property Values

Object.values() returns an array of the object’s values. You can use forEach() to loop through these values.

const person = {
    name: "Edward",
    age: 30,
    city: "Lusaka"
};

Object.values(person).forEach(value => {
    console.log(value);
});

Object.values(person) returns an array of the values in the person object, and forEach() iterates over them.

Using Object.entries() for Key-Value Pairs

Object.entries() returns an array of arrays, where each inner array is a key-value pair. This is particularly useful if you want to work with both the key and value together.

const person = {
    name: "Edward",
    age: 30,
    city: "Lusaka"
};

Object.entries(person).forEach(([key, value]) => {
    console.log(key, value);
});

Object.entries(person) creates an array of key-value pairs, and forEach() iterates over them, destructuring each pair into key and value.

Summary:

  • Use for...in to loop through all properties of an object.
  • Use Object.keys() to get an array of property names and iterate over them.
  • Use Object.values() to get an array of property values and iterate over them.
  • Use Object.entries() to get an array of key-value pairs and iterate over them.

These methods provide flexible ways to iterate over object properties depending on whether you need keys, values, or both.

Nested Objects

In JavaScript, you can have objects within objects, which are called nested objects. Nested objects are useful for representing more complex data structures, such as information with multiple levels of hierarchy.

Understanding Nested Objects

A nested object is simply an object that contains another object as one of its properties. You can access the properties of a nested object using dot notation or bracket notation, just like with regular objects.

const person = {
    name: "Edward",
    address: {
      city: "Lusaka",
      country: "Zambia"
    }
};

console.log(person.address.city); // Lusaka

In this example, the address property is itself an object, containing city and country as its properties. To access the city property, you use person.address.city.

Modifying Properties in Nested Objects

You can also modify properties within a nested object using dot notation or bracket notation, just as you would with a flat object.

Example of Modifying a Nested Object Property:

const person = {
    name: "Edward",
    address: {
      city: "Lusaka",
      country: "Zambia"
    }
};

person.address.city = "Ndola";
console.log(person.address.city); // Ndola

In this case, the city property within the address object has been changed from “Lusaka” to “Ndola”.

Adding New Properties to Nested Objects

Just like with regular objects, you can add new properties to a nested object after it’s been created.

Example of Adding a New Property to a Nested Object:

const person = {
    name: "Edward",
    address: {
      city: "Lusaka",
      country: "Zambia"
    }
};

person.address.zipCode = "10101";
console.log(person.address.zipCode); // 10101

Here, a new property zipCode is added to the address object of person.

Accessing and Modifying Deeper Levels of Nested Objects

If your object is nested multiple levels deep, you can continue to access and modify deeper properties by chaining the property names.

Example of Accessing a Deeper Nested Object:

const user = {

    profile: {
      personal: {
        name: "Lucia",
        age: 25
      },
      contact: {
        email: "lucia@example.com"
      }
    }

};

console.log(user.profile.personal.name); // Lucia

Example of Modifying a Deeper Nested Property:

const user = {

    profile: {
      personal: {
        name: "Lucia",
        age: 25
      },
      contact: {
        email: "lucia@example.com"
      }
    }

};

user.profile.personal.age = 26;
console.log(user.profile.personal.age); // 26

In these examples, the user object has a profile object, which in turn has personal and contact sub-objects. You access and modify the properties by chaining the object keys.

Summary:

  • Nested objects are objects that contain other objects as their properties.
  • You can access and modify properties within nested objects using dot or bracket notation.
  • Dot notation works best when property names are known and do not contain spaces or special characters.
  • Bracket notation is helpful when property names are dynamic or require special characters.

Object Methods

In JavaScript, objects can not only store data but also have methods—functions that are stored as properties of objects. These methods are commonly used to define behavior for objects, such as actions that the object can perform.

Adding Methods to Objects

You can add functions to objects in two ways. The first is by explicitly assigning a function to an object property.

Example of Adding a Method to an Object:

const person = {
    name: "Edward",
    greet: function() {
      console.log("Hello, " + this.name);
    }
};

person.greet(); // Hello, Edward

In this example, the greet property is a function. The this keyword refers to the current object, in this case, person. When person.greet() is called, the function outputs "Hello, Edward".

Using Shorthand Method Syntax

ES6 introduced a shorthand syntax for defining methods inside objects. This syntax simplifies the process of writing methods and makes your code more concise.

Example of Shorthand Method Syntax:

const person = {
    name: "Edward",
    greet() {
      console.log("Hello, " + this.name);
    }
};

person.greet(); // Hello, Edward

Here, the greet() method is defined without the function keyword. The shorthand method syntax is more concise and commonly used in modern JavaScript.

Accessing Object Properties Inside Methods

Inside an object method, you can use the this keyword to refer to the object itself. This is especially useful when you need to access the object’s properties from within the method.

Example of Using this in an Object Method:

const person = {
    name: "Edward",
    age: 30,
    greet() {
      console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
    }
};

person.greet(); // Hello, my name is Edward and I am 30 years old.

In this example, the method greet() uses this.name and this.age to access the properties of the person object and output a greeting.

Methods with Parameters

You can define methods that accept parameters, just like regular functions.

Example of Methods with Parameters:

const person = {
    name: "Edward",
    greet(greeting) {
      console.log(`${greeting}, ${this.name}!`);
    }
};

person.greet("Good morning"); // Good morning, Edward

In this case, the greet() method accepts a parameter greeting, which allows you to pass different greeting messages when calling the method.

Returning Values from Object Methods

Object methods can return values, just like regular functions. You can use return to send data back from the method.

Example of Returning a Value from an Object Method:

const person = {
    name: "Edward",
    greet() {
      return `Hello, ${this.name}`;
    }
};

console.log(person.greet()); // Hello, Edward

In this example, the greet() method returns a greeting string, which is then logged to the console.

Summary:

  • Methods in objects are functions that are assigned as properties of an object.
  • You can define methods using a function expression or shorthand syntax.
  • Inside methods, use this to refer to the object itself and access its properties.
  • Methods can accept parameters and return values, allowing for dynamic behavior.

Using Object.assign() to Copy Objects

The Object.assign() method is a built-in JavaScript function used to copy the properties of one or more source objects into a target object. It allows you to create a shallow copy of an object, meaning it copies the properties, but does not deeply clone any nested objects or arrays.

Basic Syntax

The syntax for Object.assign() is:

Object.assign(target, ...sources);

  • target: The object to which the properties will be copied.
  • sources: One or more source objects from which properties are copied.

Copying Properties from One Object to Another

A common use case of Object.assign() is to create a copy of an object, especially when you don’t want to directly modify the original object.

  • Example of Copying Properties:
const person1 = { name: "Edward", age: 30 };
const person2 = Object.assign({}, person1);

console.log(person2); // { name: "Edward", age: 30 }

In this example, person2 is a new object that copies all the properties from person1. The original object, person1, remains unchanged.

Merging Multiple Objects

You can use Object.assign() to merge multiple source objects into a target object. If there are any property name conflicts, the value from the last source object will overwrite the previous ones.

Example of Merging Objects:

const person = { name: "Edward", age: 30 };
const job = { title: "Engineer", company: "TechCorp" };
const contact = { email: "edward@example.com" };

const fullProfile = Object.assign({}, person, job, contact);
console.log(fullProfile);
// { name: "Edward", age: 30, title: "Engineer", company: "TechCorp", email: "edward@example.com" }

In this example, properties from the person, job, and contact objects are all merged into a new object fullProfile.

Shallow Copy with Object.assign()

Remember, Object.assign() only performs a shallow copy. This means that if any of the properties are objects or arrays, the reference to those nested objects will be copied, not the object itself.

Example of Shallow Copy:

const person1 = { name: "Edward", address: { city: "Lusaka", zip: "10101" } };
const person2 = Object.assign({}, person1);

person2.address.city = "Ndola";
console.log(person1.address.city); // Ndola
console.log(person2.address.city); // Ndola

In this example, both person1 and person2 share the same reference to the address object, so modifying one affects both.

Creating a Deep Copy

To create a deep copy (where nested objects are also copied), you’ll need to use a method like JSON.parse() and JSON.stringify() or a custom function. Object.assign() does not handle deep cloning.

For example (using JSON.stringify() and JSON.parse()):

const person1 = { name: "Edward", address: { city: "Lusaka", zip: "10101" } };
const person2 = JSON.parse(JSON.stringify(person1));

person2.address.city = "Ndola";
console.log(person1.address.city); // Lusaka
console.log(person2.address.city); // Ndola

Summary:

  • Object.assign() allows you to copy properties from one or more objects to a target object.
  • It’s useful for creating shallow copies or merging multiple objects.
  • Be aware that it performs a shallow copy, meaning nested objects are not cloned, and both the target and source will reference the same nested object.

Object Destructuring

Object destructuring is a powerful feature in JavaScript that allows you to extract properties from an object and assign them to variables in a concise and readable manner. This can be especially useful when working with objects that contain multiple properties, as it simplifies the process of accessing and using those properties.

Basic Syntax

The basic syntax for object destructuring is:

const { property1, property2 } = object;

This syntax extracts the values of property1 and property2 from the object and assigns them to variables with the same names.

Destructuring Example

Let’s say we have an object person with name and age properties:

const person = { name: "Edward", age: 30 };
const { name, age } = person;

console.log(name, age); // Edward 30

In this example:

  • { name, age } is the destructuring pattern that extracts the name and age properties from the person object and assigns them to variables name and age.
  • The output is Edward 30, as those values are now stored in the variables name and age.

Renaming Variables During Destructuring

You can rename the variables during destructuring by specifying new variable names with a colon :.

Example of Renaming Variables:

const person = { name: "Edward", age: 30 };
const { name: fullName, age: yearsOld } = person;

console.log(fullName, yearsOld); // Edward 30

In this example:

  • The name property is assigned to a new variable fullName.
  • The age property is assigned to a new variable yearsOld.

Destructuring with Default Values

You can provide default values for properties in case they are undefined or do not exist in the object.

Example with Default Values:

const person = { name: "Edward" };
const { name, age = 25 } = person;

console.log(name, age); // Edward 25

In this example, the age property does not exist in the person object, so the default value of 25 is used.

Destructuring Nested Objects

If you have nested objects, you can use destructuring to extract values from those inner objects as well.

Example with Nested Destructuring:

const person = {
    name: "Edward",
    address: {
      city: "Lusaka",
      country: "Zambia"
    }
};

const { name, address: { city, country } } = person;

console.log(name, city, country); // Edward Lusaka Zambia

In this example:

  • The address property is an object, and we use nested destructuring to extract city and country from address.

Destructuring in Function Parameters

You can use object destructuring directly in function parameters to extract specific properties when the function is called.

Example in Function Parameters:

function greet({ name, age }) {
    console.log(`Hello, ${name}. You are ${age} years old.`);
}

const person = { name: "Edward", age: 30 };
greet(person); // Hello, Edward. You are 30 years old.

In this example:

  • The greet function takes an object as an argument, and destructures the name and age properties directly in the parameter list.

Summary:

  • Object destructuring simplifies the process of extracting values from objects and assigning them to variables.
  • You can rename variables, assign default values, and even destructure nested objects.
  • It can also be used in function parameters for more concise and readable code.

Working with this Keyword

The this keyword is a special identifier in JavaScript that refers to the context in which a function is executed. When working with objects, this often refers to the object itself within methods.

Understanding this in Object Methods

Inside an object method, this refers to the object the method belongs to. This allows you to access the object’s properties and methods from within that method.

const person = {
    name: "Edward",
    greet() {
      console.log("Hello, " + this.name);
    }
};

person.greet(); // Hello, Edward

In this example:

  • The greet method is part of the person object.
  • Inside the greet method, this.name refers to the name property of the person object, so the output is “Hello, Edward”.

Using this to Access Object Properties

You can use this to access or modify properties of the object within methods.

const person = {
    name: "Edward",
    age: 30,
    updateAge(newAge) {
      this.age = newAge;
    }
};

console.log(person.age); // 30

person.updateAge(35);
console.log(person.age); // 35

In this example:

  • The updateAge method uses this.age to refer to and update the age property of the person object.

Using this in Constructor Functions

In constructor functions, this is used to assign properties to the newly created object.

function Person(name, age) {
    this.name = name;
    this.age = age;
}

const person1 = new Person("Edward", 30);
console.log(person1.name); // Edward
console.log(person1.age); // 30

In this example:

  • this.name and this.age are used to assign values to the properties of the new object created by the Person constructor function.

Arrow Functions and this

Arrow functions behave differently when it comes to this. They do not have their own this value, but inherit this from the surrounding context (lexical scoping). This can lead to unexpected results when used inside object methods.

Example with Arrow Function (incorrect usage of this):

const person = {
    name: "Edward",
    greet: () => {
      console.log("Hello, " + this.name); // `this` does not refer to `person`
    }
};

person.greet(); // undefined

In this example:

  • The greet method is an arrow function, so this does not refer to the person object. Instead, this is inherited from the surrounding context, which leads to undefined.

To avoid this issue, always use regular functions when defining methods within an object if you want this to refer to the object.

this in Callbacks

When passing methods as callbacks (e.g., in event listeners), the value of this may change depending on how the function is called.

Example with Callback (incorrect this):

const person = {
    name: "Edward",
    greet() {
      console.log("Hello, " + this.name);
    }
};

setTimeout(person.greet, 1000); // Hello, undefined (this refers to global object, not `person`)

In this example:

  • Since greet is passed as a callback to setTimeout, this inside the greet method will refer to the global object (or undefined in strict mode), not the person object.

To ensure that this refers to the correct object, you can use .bind() to explicitly bind this to the object.

Solution using bind:

setTimeout(person.greet.bind(person), 1000); // Hello, Edward

Summary of this Keyword in Objects

  • Inside an object method, this refers to the object the method belongs to.
  • You can use this to access or modify object properties and methods.
  • Arrow functions do not have their own this, so avoid using them as object methods.
  • Be careful when passing methods as callbacks, as the value of this may change. Use .bind() to explicitly set this to the desired object.

Conclusion

In this article, we’ve covered the essential aspects of working with objects in JavaScript. We learned how to:

  • Create objects using both the object literal syntax and the new Object() method.
  • Access object properties using dot notation and bracket notation.
  • Modify object properties and add new ones dynamically.
  • Delete properties and check if a property exists with the in operator or the hasOwnProperty() method.
  • Iterate over an object’s properties using loops and methods like Object.keys(), Object.values(), and Object.entries().
  • Work with nested objects and object methods.
  • Use Object.assign() for copying objects and object destructuring to extract values into variables.
  • Understand how the this keyword works within object methods.

Objects are incredibly versatile and essential in JavaScript. They can represent complex structures like users, products, settings, or even entire systems. Consider using objects in real-world projects, like building a user profile system or managing settings for an app. As you gain more experience, you’ll find that objects are an invaluable tool for structuring and organizing data in your applications.

Objects are one of the core building blocks of JavaScript and provide a powerful way to manage and manipulate data. Understanding how to use them effectively will set you up for success in working with more advanced concepts and developing real-world applications.

Scroll to Top