DEV Community

Muhammad Rizwan Ashiq
Muhammad Rizwan Ashiq

Posted on • Updated on

Object Manipulation

What is Object?

An object is a collection of properties, and a property is an association between a key and a value. A property's value can be a number, string, boolean, null, undefined, object, or function. A property's key can be any string, including an empty string.

We can create an object, assign it to a variable, add properties to it, and delete properties from it, and we can also access the values of the properties using the dot notation or the bracket notation. Consider the following example:

const obj = {
    name: "Rizwan",
    dobYear: 1996,
    isDeveloper: true,
    hobbies: ["Coding", "Gaming", "Reading"],
    age: function () {
        return 2023 - this.dobYear;
    },
    address: {
        city: "Karachi",
        country: "Pakistan",
    },
};

console.log(obj.name); // Rizwan
console.log(obj.dobYear); // 1996
console.log(obj.isDeveloper); // true
console.log(obj.hobbies); // ["Coding", "Gaming", "Reading"]
console.log(obj.age); // 27
console.log(obj.address); // { city: 'Karachi', country: 'Pakistan' }

delete obj.isDeveloper; // delete property from object

console.log(obj.isDeveloper); // undefined

// add new property to object

obj.stacks = ["JavaScript", "React", "Node"];

// update property value

obj.name = "Rizwan Ashiq";

// Can also use bracket notation to access properties

console.log(obj["name"]); // Rizwan Ashiq
console.log(obj["dobYear"]); // 1996
console.log(obj["hobbies"]); // ["Coding", "Gaming", "Reading"]
Enter fullscreen mode Exit fullscreen mode

Setting properties of undefined

Consider the following example:

const obj = {
    name: "Rizwan",
};

// This will error
obj.address.city = "Karachi"; // Cannot set properties of undefined (setting 'city')
Enter fullscreen mode Exit fullscreen mode

In the above example, we are trying to access (update) the city property of the address property of the obj object. But the address property is not defined in the obj object. So, we will get an error. To avoid this error, we can use the && operator, or optional chaining ? to check if the address property is defined or not.

const obj = {
    name: "Rizwan",
}

// And operator
obj.address && (obj.address.city = "Karachi");
// It will not throw an error, but it will simply not move forward after the && operator.

// Optional chaining
obj.address?.city = "Karachi";
// Same as above, if the address property is not defined, it will not go forward.
Enter fullscreen mode Exit fullscreen mode

Even if the address property is not defined, the above code will not throw an error, but it will not create the address property either. To create the address property, we can use the ternary operator.

const obj = {
    name: "Rizwan",
};

// Ternary operator
obj.address
    ? (obj.address.city = "Karachi")
    : (obj.address = { city: "Karachi" });
Enter fullscreen mode Exit fullscreen mode

for..in loop

The for..in loop iterates over the enumerable properties of an object, in an arbitrary order. For each distinct property, statements can be executed.

const obj = {
    name: "Rizwan",
    dobYear: 1996,
    isDeveloper: true,
    hobbies: ["Coding", "Gaming", "Reading"],
    age: function () {
        return 2023 - this.dobYear;
    },
    address: {
        city: "Karachi",
        country: "Pakistan",
    },
};


for (let key in obj) {
    console.log(key); // name, dobYear, isDeveloper, hobbies, age, address
    console.log(obj[key]); 
    // Rizwan, 1996, true, ["Coding", "Gaming", "Reading"], 27, { city: 'Karachi', country: 'Pakistan' }
}
Enter fullscreen mode Exit fullscreen mode

It's good tool to iterate over the object properties.

What is enumerable property?

It's a lot more boring than something that should be visualized 😒. And you won't be dealing with this. It's just for information.

An enumerable property is one that can be included in and visited during for..in loops (or a similar iteration of properties, like Object.keys()). By default, all properties of an object are enumerable, unless you set the enumerable attribute to false.

const person = { age: 18 };
Object.defineProperty(person, "name", { value: "Joshua", enumerable: false });

person.name; // 'Joshua'
for (prop in person) {
    console.log(prop);
} // 'age'
Object.keys(person); // ['age']
Object.getOwnPropertyNames(person); // ['age', 'name'] (non-enumerable properties are included)
Enter fullscreen mode Exit fullscreen mode

Object Methods

In JavaScript, there are many methods that we can use to manipulate objects. Here are some of them:

  • Object.keys()
  • Object.values()
  • Object.entries()
  • Object.fromEntries()
  • Object.assign()
  • Object.seal()
  • Object.freeze()
  • Object.preventExtensions()
  • Object.isSealed()
  • Object.isFrozen()
  • Object.isExtensible()
  • Object.is()

Object.keys()

Returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

console.log(Object.keys(obj)); // [ 'name', 'age', 'city' ]
Enter fullscreen mode Exit fullscreen mode

By using Object.keys() we can get all the keys of an object and then we can use forEach loop to iterate over the keys and get the values of the object.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

Object.keys(obj).forEach((key) => {
    console.log(obj[key]); // Rizwan, 25, Rahim Yar Khan
});
Enter fullscreen mode Exit fullscreen mode

By using Object.keys() we can also get the length of an object.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

console.log(Object.keys(obj).length); // 3
Enter fullscreen mode Exit fullscreen mode

You can also use Object.keys() to check if an object is empty or not.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

if (Object.keys(obj).length === 0) {
    console.log("Object is empty");
} else {
    console.log("Object is not empty");
}
Enter fullscreen mode Exit fullscreen mode

I would recommend you to play with Object.keys() and you will find many more use cases of it 😊

Object.values()

Returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

console.log(Object.values(obj)); // [ 'Rizwan', 25, 'Rahim Yar Khan' ]
Enter fullscreen mode Exit fullscreen mode

Object.entries()

Returns an array of a given object's own enumerable string-keyed property [key, value] pairs, in the same order as that provided by a for...in loop. The order of the array returned by Object.entries() does not depend on how an object is defined. If there is a need for certain ordering, then the array should be sorted first like Object.entries(obj).sort((a, b) => b[0].localeCompare(a[0]));.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

console.log(Object.entries(obj)); // [ [ 'name', 'Rizwan' ], [ 'age', 25 ], [ 'city', 'Rahim Yar Khan' ] ]
Enter fullscreen mode Exit fullscreen mode

Object.fromEntries()

The Object.fromEntries() method transforms a list of key-value pairs into an object.

const arr = [
    ["name", "Rizwan"],
    ["age", 25],
    ["city", "Rahim Yar Khan"],
];

console.log(Object.fromEntries(arr)); // { name: 'Rizwan', age: 25, city: 'Rahim Yar Khan' }
Enter fullscreen mode Exit fullscreen mode

Object.assign()

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.

const obj1 = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

const obj2 = {
    country: "Pakistan",
};

const obj3 = Object.assign(obj1, obj2);

console.log(obj3); // { name: 'Rizwan', age: 25, city: 'Rahim Yar Khan', country: 'Pakistan' }
Enter fullscreen mode Exit fullscreen mode

Shallow copy can also do the same thing as Object.assign().

const obj1 = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

const obj2 = {
    country: "Pakistan",
};

const obj3 = { ...obj1, ...obj2 };

console.log(obj3); // { name: 'Rizwan', age: 25, city: 'Rahim Yar Khan', country: 'Pakistan' }
Enter fullscreen mode Exit fullscreen mode

Object.assign() is better cause in shallow copy the problem is, if we have a nested object in the source object, then it will only copy the reference of that nested object. So if we change the nested object in the source object, then it will also change in the target object.

const obj1 = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
    address: {
        street: "Main Road",
        house: 123,
    },
};

const obj2 = {
    country: "Pakistan",
};

const obj3 = { ...obj1, ...obj2 }; // shallow copy

obj3.address.house = 456; // change house number in obj3, it will also change in obj1

console.log(obj1); // { name: 'Rizwan', age: 25, city: 'Rahim Yar Khan', address: { street: 'Main Road', house: 456 } }
console.log(obj3); // { name: 'Rizwan', age: 25, city: 'Rahim Yar Khan', address: { street: 'Main Road', house: 456 }, country: 'Pakistan' }
Enter fullscreen mode Exit fullscreen mode

:::

Object.seal()

The Object.seal() method seals an object, preventing new properties from being added to it and marking all existing properties as non-configurable. Values of present properties can still be changed as long as they are writable.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

Object.seal(obj);

obj.country = "Pakistan"; // It will not add country property to obj, and it will not throw any error
obj.name = "Rizwan Khan"; // It will change the value of name property
delete obj.city; // It will not delete city property from obj, and it will not throw any error

console.log(obj); // { name: 'Rizwan', age: 25, city: 'Rahim Yar Khan' }
Enter fullscreen mode Exit fullscreen mode

Object.freeze()

The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

Object.freeze(obj);

obj.country = "Pakistan"; // It will not add country property to obj, and it will not throw any error
obj.name = "Ali"; // It will not change the name property, and it will not throw any error
delete obj.city; // It will not delete the city property, and it will not throw any error

console.log(obj); // { name: 'Rizwan', age: 25, city: 'Rahim Yar Khan' }
Enter fullscreen mode Exit fullscreen mode

Object.preventExtensions()

The Object.preventExtensions() method prevents new properties from ever being added to an object (i.e. prevents future extensions to the object).

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

Object.preventExtensions(obj);

obj.country = "Pakistan"; // It will not add country property to obj, and it will not throw any error
obj.name = "Ali"; // It will change the name property
delete obj.city; // It will delete the city property

console.log(obj); // { name: 'Ali', age: 25 }
Enter fullscreen mode Exit fullscreen mode

Object.isSealed()

The Object.isSealed() method determines if an object is sealed.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

Object.seal(obj);

console.log(Object.isSealed(obj)); // true
Enter fullscreen mode Exit fullscreen mode

Object.isFrozen()

The Object.isFrozen() method determines if an object is frozen.

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

Object.freeze(obj);

console.log(Object.isFrozen(obj)); // true
Enter fullscreen mode Exit fullscreen mode

Object.isExtensible()

The Object.isExtensible() method determines if an object is extensible (whether it can have new properties added to it).

const obj = {
    name: "Rizwan",
    age: 25,
    city: "Rahim Yar Khan",
};

Object.preventExtensions(obj);

console.log(Object.isExtensible(obj)); // false
Enter fullscreen mode Exit fullscreen mode

Object.seal() VS Object.freeze() VS Object.preventExtensions()

Difference between Object.seal(), Object.freeze() and Object.preventExtensions() is that Object.seal() and Object.freeze() make the object non-extensible, but Object.preventExtensions() doesn't make the object non-configurable and non-writable.

Image

Object.is()

The Object.is() method determines whether two values are the same value.

console.log(Object.is(1, 1)); // true
console.log(Object.is(1, "1")); // false
console.log(Object.is(NaN, NaN)); // true
Enter fullscreen mode Exit fullscreen mode

Operators

in operator

The in operator is used to check if an object has a specific property. It returns true if the object has the property, and it returns false if the object does not have the property.

Here is an example of how to use the in operator:

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

console.log("name" in person); // Output: true
console.log("age" in person); // Output: true

console.log("firstName" in person); // Output: false
console.log("lastName" in person); // Output: false
Enter fullscreen mode Exit fullscreen mode

Summary

In this chapter, we learned about objects in JavaScript. We learned about the different ways to create objects in JavaScript. We also learned about the different ways to access the properties of an object. We learned about the different ways to add, update, and delete the properties of an object. We learned about the different ways to iterate over the properties of an object. We learned about the different ways to copy an object. We learned about the different methods to seal, freeze, and prevent extensions of an object. We learned about the Object.is() method. We learned about the different ways to check if an object is sealed, frozen, or extensible. We learned about the different ways to check if two values are the same value.

Method Description
Object.keys() Returns an array of a given object's own enumerable property names, iterated in the same order that a normal loop would.
Object.values() Returns an array of a given object's own enumerable property values, in the same order as that provided by a for...in loop.
Object.entries() Returns an array of a given object's own enumerable string-keyed property [key, value] pairs, in the same order as that provided by a for...in loop.
Object.assign() Copies all enumerable own properties from one or more source objects to a target object. It returns the target object.
Object.seal() Prevents new properties from being added to an object and marks all existing properties as non-configurable.
Object.freeze() Prevents new properties from being added to an object, existing properties from being removed, prevents changing the enumerability, configurability, or writability of existing properties, and prevents the values of existing properties from being changed.
Object.preventExtensions() Prevents new properties from ever being added to an object (i.e. prevents future extensions to the object).
Object.isSealed() Determines if an object is sealed.
Object.isFrozen() Determines if an object is frozen.
Object.isExtensible() Determines if an object is extensible (whether it can have new properties added to it).
Object.is() Determines whether two values are the same value.

Top comments (0)