Welcome to Day 7 of our 30-day JavaScript and Node.js learning series! In the last article, we introduced you to the JavaScript Arrays. Today, we’ll dive deeper into one of the most crucial topics—JavaScript Objects.
Objects are a fundamental data type in JavaScript, serving as building blocks for creating complex applications. They are essentially collections of key-value pairs, where keys are called properties and values can be of any data type. Understanding objects is crucial for mastering JavaScript programming.
In this comprehensive guide, we’ll delve into the intricacies of objects. We’ll explore how to create, access, and modify them. We’ll also learn how to use them effectively.
Creating Objects
There are two primary ways to create objects in JavaScript:
- Object Literal Notation:
const person = {
firstName: "John",
lastName: "Doe",
age: 30,
city: "New York",
greet: function() {
console.log("Hello, my name is " + this.firstName + " " + this.lastName);
}
};
2. By Creating an Instance of Object Directly
const person = new Object();
person.firstName = "John";
person.lastName = "Doe";
person.age = 30;
person.city = "New York";
3. Constructor Functions:
function Person(firstName, lastName, age, city) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.city = city;
this.greet = function() {
console.log("Hello, my name is " + this.firstName + " " + this.lastName);
};
}
const person1 = new Person("Alice", "Smith", 25, "Los Angeles");
Choosing the Right Method
- Object Literal Notation: Ideal for creating simple objects with a fixed structure.
- Constructor Functions: Suitable for creating complex objects with multiple instances and inheritance.
Accessing and modifying Properties
Once an object is created, you can access, add, and modify its properties:
- Accessing Properties:
console.log(person.firstName); // Output: John
console.log(person["lastName"]); // Output: Doe
- Adding Properties:
person.occupation = "Developer";
- Modifying Properties:
person.age = 31;
Object Methods
Objects can have methods, which are functions defined within the object. Methods are used to perform actions on the object’s data.
Built-in Methods
JavaScript provides several built-in methods for objects:
Object Manipulation Methods:
Object.assign(target, ...sources)
:- Copies own enumerable properties from one or more source objects to a target object.
- Does not copy non-enumerable properties (properties set with
enumerable: false
usingObject.defineProperty
). - Overwrites existing properties in the target object with properties from sources, based on property names.
- Returns the modified target object.
- Example:
const person = { name: "John" };
const details = { age: 30, city: "New York" };
const combined = Object.assign(person, details); // combined: { name: "John", age: 30, city: "New York" }
Object.create(prototype[, propertiesObject])
:- Creates a new object that uses the specified prototype object.
- The prototype object is used for property lookup when properties are accessed on the newly created object.
- Optionally, you can provide a second argument,
propertiesObject
, to define specific properties on the new object. - Example:
function Person(name) { this.name = name; }
const person1 = new Person("Alice"); // person1 inherits from Person.prototype
const person2 = Object.create(Person.prototype, { age: { value: 25, writable: true } }); // person2 inherits from Person.prototype with a custom "age" property
Property Definition and Access Methods:
Object.defineProperty(obj, prop, descriptor)
:- Defines a new property directly on an object (
obj
), or modifies an existing property. - Takes three arguments:
obj
: The object to define the property on.prop
: The name of the property (string or symbol).descriptor
: An object that describes the property (with properties likevalue
,writable
,enumerable
,configurable
).
- Example:
- Defines a new property directly on an object (
const person = {};
Object.defineProperty(person, "name", { value: "John", writable: true, enumerable: true });
console.log(person.name); // Output: John
Object.defineProperties(obj, propertiesObject)
:- Defines multiple properties on an object at once.
- Takes two arguments:
obj
: The object to define the properties on.propertiesObject
: An object whose properties will be defined on the target object.
- Example:
const person = {};
Object.defineProperties(person, {
name: { value: "John", writable: true },
age: { value: 30, writable: false }
});
console.log(person.name); // Output: John
person.age = 31; // Throws an error because "age" is not writable
Object.entries(obj)
:- Returns an array of key-value pairs from an object’s own enumerable properties.
- Each element in the array is an array of [key, value].
- Example:
const person = { name: "John", age: 30 };
const entries = Object.entries(person); // entries: [["name", "John"], ["age", 30]]
Object.freeze(obj)
:- Prevents modifications to an object’s existing properties (value, writable, configurable).
- Attempts to modify a frozen object’s properties will throw a
TypeError
. - Frozen objects cannot be further modified.
- Example:
const person = { name: "John" };
Object.freeze(person);
person.name = "Alice"; // Throws a TypeError because the object is frozen
Object.getOwnPropertyDescriptor(obj, prop)
:- Returns a property descriptor object for a specified property (
prop
) on an object (obj
). - The descriptor object describes the property’s characteristics (value, writable, enumerable, configurable).
- Example:
- Returns a property descriptor object for a specified property (
const person = { name: "John" };
const descriptor = Object.getOwnPropertyDescriptor(person, "name");
console.log(descriptor); // { value: "John", writable: true, enumerable: true, configurable: true }
Object.getOwnPropertyDescriptors(obj)
:- Returns an object containing all own property descriptors for an object.
- Similar to
Object.getOwnPropertyDescriptor
but returns all properties at once. - Example:
const person = { name: "John", age: 30 };
const descriptors = Object.getOwnPropertyDescriptors(person);
console.log(descriptors); // { name: { ... }, age: { ... } } (details of each property descriptor)
Object.getOwnPropertyNames(obj)
:- Returns an array of all own property names (strings) of an object.
- Only enumerable properties are included.
- Example:
const person = { name: "John", age: 30, _secret: "" }; // _secret is not enumerable by default
const propertyNames = Object.getOwnPropertyNames(person); // propertyNames: ["name", "age"]
Object.getOwnPropertySymbols(obj)
:- Returns an array of all own property names (symbols) of an object.
- Only enumerable properties are included.
- Example:
const person = { name: "John", age: 30, [Symbol.for("secret")]: "" }; // Symbol property
const propertySymbols = Object.getOwnPropertySymbols(person); // propertySymbols: [Symbol(secret)]
Object.getPrototypeOf(obj)
:- Returns the object’s prototype (the object that the current object inherits from).
- If the object has no prototype (e.g.,
Object.create(null)
), it returnsnull
. - Example:
function Person() {}
const person1 = new Person();
console.log(Object.getPrototypeOf(person1)); // Output: Person.prototype
Object.is(value1, value2)
:- Determines if two values are exactly the same.
- Handles special cases like
NaN
,0
, and-0
more reliably than==
.Example
Object.isExtensible(obj)
:- Checks if an object can be extended (new properties can be added).
- Returns
true
if the object is extensible,false
otherwise. - Example:
const person = {};
console.log(Object.isExtensible(person)); // Output: true
Object.preventExtensions(person);
console.log(Object.isExtensible(person)); // Output: false
Object.isFrozen(obj)
:- Checks if an object is frozen (no modifications are allowed).
- Returns
true
if the object is frozen,false
otherwise. - Example:
const person = {};
Object.freeze(person);
console.log(Object.isFrozen(person)); // Output: true
Object.isSealed(obj)
:- Checks if an object is sealed (no new properties can be added, but existing properties can be modified).
- Returns
true
if the object is sealed,false
otherwise. - Example:
const person = {};
Object.seal(person);
console.log(Object.isSealed(person)); // Output: true
Object.keys(obj)
:- Returns an array of an object’s own enumerable property names (strings).
- Example:
const person = { name: "John", age: 30 };
const keys = Object.keys(person); // keys: ["name", "age"]
Object.preventExtensions(obj)
:- Prevents new properties from being added to an object.
- Existing properties can still be modified.
- Example:
const person = {};
Object.preventExtensions(person);
person.city = "New York"; // Throws a TypeError
Object.seal(obj)
:- Prevents both new properties from being added and existing properties as non-configurable.
- Similar to
Object.freeze
but allows existing properties to be modified. - Example:
const person = {
name: "Clara"
};
Object.seal(person);
person.city = "New York"; // Throws a TypeError
person.name = "Alice"; // Allowed (existing property can be modified)
delete person.city; // Throws a TypeError
Object.setPrototypeOf(obj, proto)
:- Sets the prototype of an object.
- Replaces the existing prototype with the specified
proto
object. - Example:
const person = {};
const personPrototype = { greet: function() { console.log("Hello!"); } };
Object.setPrototypeOf(person, personPrototype);
person.greet(); // Output: Hello!
Object.values(obj)
:- Returns an array of an object’s own enumerable property values.
- Example:
const person = { name: "John", age: 30 };
const values = Object.values(person); // values: ["John", 30]
Custom Methods
You can also define your own custom methods on objects:
const person = {
firstName: "John",
lastName: "Doe",
age: 30,
greet: function() {
console.log("Hello, my name is " + this.firstName + " " + this.lastName);
},
getFullName: function() {
return this.firstName + " " + this.lastName;
}
};
Nested Objects
Objects can be nested within other objects:
const address = {
street: "123 Main St",
city: "New York",
zipCode: "10001"
};
const person = {
firstName: "John",
lastName: "Doe",
age: 30,
address: address
};
Arrays as Properties
Objects can have arrays as properties:
const person = {
firstName: "John",
lastName: "Doe",
hobbies: ["reading", "hiking", "programming"]
};
Object Prototypes
In JavaScript, objects inherit properties and methods from their prototype. The prototype chain allows objects to access properties and methods defined on their prototype and its parent prototypes.
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
Person.prototype.greet = function() {
console.log("Hello, my name is " + this.firstName + " " + this.lastName);
};
const person1 = new Person("Alice", "Smith");
person1.greet(); // Output: Hello, my name is Alice Smith
When to Use Prototypes
Prototypes are useful for creating reusable code and implementing inheritance. They can be especially helpful when you need to define common properties and methods for multiple objects.
Object Copying and Cloning
When you assign one object to another, both variables will reference the same object in memory. This means that any changes made to one object will also be reflected in the other.
To create a true copy of an object, you can use the Object.assign()
method or the spread operator:
const person = {
firstName: "John",
lastName: "Doe",
age: 30
};
// Using Object.assign()
const personCopy = Object.assign({}, person);
// Using the spread operator
const personCopy2 = { ...person };
Now, personCopy
and personCopy2
are independent copies of the original person
object. Changes made to one copy will not affect the other.
Conclusion
Objects are a fundamental data type in JavaScript, providing a flexible and powerful way to represent data and encapsulate behavior. By understanding how to create, manipulate, and use objects effectively, you can build robust and scalable JavaScript applications.
In our next post we will explore ES6+ Features in JavaScript.
Previous Lesson
Day 6: Javascript Arrays
Next Lesson
Day 8: ES6+ Features in JavaScript
Share with your friends
Pingback: JavaScript Arrays – Equitem
Pingback: ES6+ Features in JavaScript – Equitem
Pingback: JavaScript Prototypes and Inheritance – Equitem