Objects
Objects are a fundamental building block in JavaScript. They enable you to represent and handle complex data structures. In this module, you’ll learn how to create and manipulate objects in JavaScript, including adding, removing, and modifying values. Additionally, you’ll understand how to use objects in conjunction with functions and arrays.
What is an object in JS
In essence, objects are simply hash tables with unique keys and their corresponding values.
There are several ways to create objects:
- Bracket notation
- Dot notation
- Curly braces notation
By default, objects can be created using:
new Object(){}
Objects inherit methods like toString() because of their prototype:
let o1 = new Object();
console.log(o1["toString"]()); // [object Object]
console.log(o1.toString()); // [object Object]
let o2 = {};
console.log(o2["toString"]()); // [object Object]
console.log(o2.toString()); // [object Object]
Bracket Notation
Using the bracket notation, you can dynamically set or get object properties:
let p1 = {};
p1["name"] = "Mathias";
p1["birthYear"] = 2006;
p1["estimatedAge"] = function () {
return new Date().getFullYear() - this["birthYear"];
};
p1["toString"] = function () {
console.log(`My name is ${this["name"]} and I am ${this["estimatedAge"]()} years old`);
};
p1["toString"](); // My name is Mathias and I am 19 years old
Dot Notation
Dot notation is a concise way to access object properties:
let p2 = {};
p2.name = "Mikkel";
p2.birthYear = 2003;
p2.estimatedAge = function () {
return new Date().getFullYear() - this.birthYear;
};
p2.toString = function () {
console.log(`My name is ${this.name} and I am ${this.estimatedAge()} years old`);
};
p2.toString(); // My name is Mikkel and I am 22 years old
Curly Braces Notation
Using curly braces, you can define an object and its properties/methods all at once:
let p3 = {
name: "Michell",
birthYear: 1966,
estimatedAge: function () {
return new Date().getFullYear() - this.birthYear;
},
toString: function () {
console.log(`My name is ${this.name} and I am ${this.estimatedAge()} years old`);
},
};
p3.toString(); // My name is Michell and I am 59 years old
Combining Notations
It’s possible to mix and match the notations when working with objects:
let p4 = {};
p4["name"] = "Lene";
p4.birthYear = 1964;
p4["estimatedAge"] = function () {
return new Date().getFullYear() - this.birthYear;
};
p4.toString = function () {
console.log(`My name is ${this.name} and I am ${this["estimatedAge"]()} years old`);
};
p4.toString(); // My name is Lene and I am 61 years old
Adding and Removing Properties
You can dynamically add or remove properties from an object:
let p5 = {
name: "Villads",
birthYear: 2017,
estimatedAge: function () {
return new Date().getFullYear() - this.birthYear;
},
toString: function () {
console.log(`My name is ${this.name} and I am ${this.estimatedAge()} years old`);
},
};
p5.toString(); // My name is Villads and I am 8 years old
p5.yearsTo18 = function () {
return 18 - this.estimatedAge();
};
delete p5.name;
p5.toString(); // My name is undefined and I am 8 years old
Iterating Over Keys
You can loop through an object’s properties using a for...in loop:
let p6 = {
navn: "Villads",
fødselsår: 2017,
estimeretAlder: function () {
return new Date().getFullYear() - this.fødselsår;
},
toString: function () {
console.log(
`Jeg hedder ${this.navn} og er ${this.estimeretAlder()} gammel`
);
},
};
p6.toString(); // Jeg hedder Villads og er 8 gammel
for (const key in p6) {
console.log(key + " = " + typeof p6[key]);
}
/*
navn = string
fødselsår = number
estimeretAlder = function
toString = function
*/
for (const key in p6) {
console.log(`${key}: ${p6[key]}`);
}
/*
navn: Villads
fødselsår: 2017
estimeretAlder: function () {
return new Date().getFullYear() - this.fødselsår;
}
toString: function () {
console.log(`Jeg hedder ${this.navn} og er ${this.estimeretAlder()} gammel`);
}
*/
for (const key in p6) {
if (typeof p6[key] === "function") {
p6[key]();
} else {
console.log(`${key}: ${p6[key]}`);
}
}
/*
navn: Villads
fødselsår: 2017
Jeg hedder Villads og er 8 gammel
*/
Arrays of Objects
Objects can be elements within an array:
let toString = function () {
console.log(
`Jeg hedder ${this.navn} og er ${this.estimeretAlder()} gammel`
);
};
let estimeretAlder = function () {
return new Date().getFullYear() - this.fødselsår;
};
let personer = [
{
navn: "Michell",
fødselsår: 1966,
estimeretAlder: estimeretAlder,
toString: toString,
},
{
navn: "Lene",
fødselsår: 1964,
estimeretAlder: estimeretAlder,
toString: toString,
},
];
personer.push({
navn: "Mikkel",
fødselsår: 2003,
estimeretAlder: estimeretAlder,
toString: toString,
});
let m = {};
m.navn = "Mathias";
m.fødselsår = 2006;
m.estimeretAlder = estimeretAlder;
m.toString = toString;
personer.push(m);
console.log(personer.length); // 4
for (let i = 0; i < personer.length; i++) {
personer[i].toString();
}
/*
Jeg hedder Michell og er 59 gammel
Jeg hedder Lene og er 61 gammel
Jeg hedder Mikkel og er 22 gammel
Jeg hedder Mathias og er 19 gammel
*/
for (const person of personer) {
person.toString();
}
/*
Jeg hedder Michell og er 59 gammel
Jeg hedder Lene og er 61 gammel
Jeg hedder Mikkel og er 22 gammel
Jeg hedder Mathias og er 19 gammel
*/
JSON
Use the JSON object to serialize (stringify) an object into a string and deserialize (parse) from a string back to an object:
let toString = function () {
console.log(
`Jeg hedder ${this.navn} og er ${this.estimeretAlder()} gammel`
);
};
let estimeretAlder = function () {
return new Date().getFullYear() - this.fødselsår;
};
let personer = [
{
navn: "Michell",
fødselsår: 1966,
estimeretAlder: estimeretAlder,
toString: toString,
},
{
navn: "Lene",
fødselsår: 1964,
estimeretAlder: estimeretAlder,
toString: toString,
},
];
let json = JSON.stringify(personer);
console.log(json);
// [{"navn":"Michell","fødselsår":1966},{"navn":"Lene","fødselsår":1964}]
let personer2 = JSON.parse(json);
console.log(personer2); // objekt
console.log(personer2.length); // 2
JSON.stringify() and functions
Note that JSON.stringify() does not include functions when serializing objects. Only data properties (strings, numbers, booleans, arrays, objects) are included in the JSON output. This is why the estimeretAlder and toString methods are missing from the JSON string above.
If you need to preserve methods, you’ll need to reconstruct them after parsing:
let personer2 = JSON.parse(json);
// Add methods back after parsing
personer2.forEach(person => {
person.estimeretAlder = estimeretAlder;
person.toString = toString;
});
Destructuring
Destructuring is a convenient way to extract values from arrays or properties from objects into distinct variables. Introduced in ES6, it makes code cleaner and more readable.
Object Destructuring
Extract properties from objects:
// Traditional way
const person = { name: 'John', age: 30, city: 'Copenhagen' };
const name = person.name;
const age = person.age;
// Destructuring way
const { name, age, city } = person;
console.log(name); // "John"
console.log(age); // 30
console.log(city); // "Copenhagen"
Renaming Variables:
const person = { name: 'Alice', age: 25 };
const { name: personName, age: personAge } = person;
console.log(personName); // "Alice"
console.log(personAge); // 25
// console.log(name); // Error: name is not defined
Default Values:
const person = { name: 'Bob' };
const { name, age = 30, city = 'Unknown' } = person;
console.log(name); // "Bob"
console.log(age); // 30 (default)
console.log(city); // "Unknown" (default)
Nested Destructuring:
const person = {
name: 'Alice',
address: {
city: 'Copenhagen',
country: 'Denmark'
}
};
const { name, address: { city, country } } = person;
console.log(name); // "Alice"
console.log(city); // "Copenhagen"
console.log(country); // "Denmark"
Rest Pattern with Objects:
const person = { name: 'Alice', age: 25, city: 'Copenhagen', job: 'Developer' };
const { name, age, ...otherInfo } = person;
console.log(name); // "Alice"
console.log(age); // 25
console.log(otherInfo); // { city: "Copenhagen", job: "Developer" }
Destructuring Function Parameters
Destructuring is particularly useful with function parameters:
// Without destructuring
function displayPerson(person) {
console.log(`${person.name} is ${person.age} years old`);
}
// With destructuring
function displayPerson({ name, age }) {
console.log(`${name} is ${age} years old`);
}
const person = { name: 'Alice', age: 25, city: 'Copenhagen' };
displayPerson(person); // "Alice is 25 years old"
// With default values
function displayPerson({ name, age, city = 'Unknown' }) {
console.log(`${name}, ${age}, from ${city}`);
}
displayPerson({ name: 'Bob', age: 30 }); // "Bob, 30, from Unknown"
Practical Example: API Response
// Common use case: extracting data from API responses
const apiResponse = {
status: 'success',
data: {
user: {
id: 123,
name: 'Alice Johnson',
email: 'alice@example.com'
},
posts: [1, 2, 3]
}
};
// Extract nested data cleanly
const {
status,
data: {
user: { name, email },
posts
}
} = apiResponse;
console.log(status); // "success"
console.log(name); // "Alice Johnson"
console.log(email); // "alice@example.com"
console.log(posts); // [1, 2, 3]
When to Use Destructuring
Destructuring is great for:
- Extracting multiple values at once
- Function parameters (especially with options objects)
- Working with API responses
- Making code more readable and concise
However, don’t overuse it - deep nested destructuring can become hard to read.
Summary
Objects are versatile data structures in JavaScript that allow you to organize and manipulate related data and functionality.
Key Takeaways
Creating Objects:
- Objects are hash tables with key-value pairs
- Three ways to create:
new Object(),{}(preferred), or with properties inline - Objects inherit methods like
toString()from their prototype
Accessing Properties:
- Bracket notation:
obj["property"]- useful for dynamic property names - Dot notation:
obj.property- cleaner and more common - Both notations can be mixed in the same code
Manipulating Objects:
- Add properties:
obj.newProperty = value - Remove properties:
delete obj.property - Properties can be added or removed at any time
- Property values can be any type: primitives, functions, objects, arrays
Iterating Objects:
- Use
for...inloop to iterate over all enumerable properties - Check property type with
typeof obj[key] - Filter properties by type to process data vs. methods differently
Objects in Arrays:
- Objects can be stored in arrays
- Useful for collections of related items (users, products, etc.)
- Iterate with regular loops or
for...of - Methods can be shared between objects for consistency
JSON Serialization:
JSON.stringify()converts objects to JSON stringsJSON.parse()converts JSON strings back to objects- Functions are NOT included in JSON serialization
- Only data properties are preserved (strings, numbers, booleans, arrays, objects)
Best Practices:
- Prefer
{}overnew Object()for creating objects - Use dot notation when property names are known
- Use bracket notation for dynamic property access
- Remember that
deleteonly removes the property, doesn’t set it toundefined - Be aware that JSON.stringify drops functions
Understanding objects is fundamental to JavaScript programming, as they are used everywhere - from simple data structures to complex application state management.