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"]
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')
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.
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" });
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' }
}
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)
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' ]
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
});
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
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");
}
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' ]
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' ] ]
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' }
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' }
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' }
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' }
:::
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' }
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' }
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 }
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
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
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
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.
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
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
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)