Objects
Objects are collections of key-value pairs that allow you to store and organize data. They are fundamental to JavaScript and form the basis of object-oriented programming.
Creating Objects
Object Literal
let person = {
name: 'John',
age: 30,
isStudent: false,
hobbies: ['reading', 'coding']
};
Constructor Function
function Person(name, age) {
this.name = name;
this.age = age;
this.greet = function() {
return `Hello, my name is ${this.name}`;
};
}
let john = new Person('John', 30);
Object.create()
let personPrototype = {
greet: function() {
return `Hello, my name is ${this.name}`;
}
};
let john = Object.create(personPrototype);
john.name = 'John';
john.age = 30;
ES6 Classes
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, my name is ${this.name}`;
}
}
let john = new Person('John', 30);
Accessing Properties
Dot Notation
let person = { name: 'John', age: 30 };
console.log(person.name); // 'John'
console.log(person.age); // 30
person.age = 31; // Modify property
Bracket Notation
let person = { name: 'John', age: 30 };
console.log(person['name']); // 'John'
console.log(person['age']); // 30
let property = 'name';
console.log(person[property]); // 'John'
// Useful for dynamic property names
let key = 'age';
person[key] = 31;
Adding and Modifying Properties
let person = { name: 'John' };
// Add new property
person.age = 30;
person['isStudent'] = false;
// Modify existing property
person.name = 'Jane';
// Add method
person.greet = function() {
return `Hello, I'm ${this.name}`;
};
Deleting Properties
let person = { name: 'John', age: 30, city: 'New York' };
delete person.city; // Remove property
console.log(person.city); // undefined
// Cannot delete inherited properties
delete person.toString; // Won't work
Object Methods
Object.keys()
let person = { name: 'John', age: 30, city: 'New York' };
let keys = Object.keys(person); // ['name', 'age', 'city']
Object.values()
let person = { name: 'John', age: 30, city: 'New York' };
let values = Object.values(person); // ['John', 30, 'New York']
Object.entries()
let person = { name: 'John', age: 30, city: 'New York' };
let entries = Object.entries(person); // [['name', 'John'], ['age', 30], ['city', 'New York']]
Object.assign()
let person = { name: 'John', age: 30 };
let job = { title: 'Developer', company: 'Tech Corp' };
let employee = Object.assign({}, person, job);
// { name: 'John', age: 30, title: 'Developer', company: 'Tech Corp' }
// Shallow copy
let copy = Object.assign({}, person);
Object.freeze()
let person = { name: 'John', age: 30 };
Object.freeze(person);
person.age = 31; // Won't work in strict mode
delete person.name; // Won't work
person.city = 'New York'; // Won't work
Object.seal()
let person = { name: 'John', age: 30 };
Object.seal(person);
person.age = 31; // Works
delete person.name; // Won't work
person.city = 'New York'; // Won't work
Iterating Over Objects
for...in Loop
let person = { name: 'John', age: 30, city: 'New York' };
for (let key in person) {
console.log(`${key}: ${person[key]}`);
}
// Check if property is own property
for (let key in person) {
if (person.hasOwnProperty(key)) {
console.log(`${key}: ${person[key]}`);
}
}
Object.keys() with forEach
let person = { name: 'John', age: 30, city: 'New York' };
Object.keys(person).forEach(key => {
console.log(`${key}: ${person[key]}`);
});
for...of with Object.entries()
let person = { name: 'John', age: 30, city: 'New York' };
for (let [key, value] of Object.entries(person)) {
console.log(`${key}: ${value}`);
}
Object Destructuring
let person = { name: 'John', age: 30, city: 'New York' };
// Extract properties
let { name, age } = person;
console.log(name, age); // 'John' 30
// With default values
let { name: personName, age: personAge, country = 'USA' } = person;
console.log(personName, personAge, country); // 'John' 30 'USA'
// Nested destructuring
let user = {
name: 'John',
address: {
city: 'New York',
zip: '10001'
}
};
let { name, address: { city, zip } } = user;
console.log(city, zip); // 'New York' '10001'
Computed Property Names
let prop = 'name';
let person = {
[prop]: 'John',
['age']: 30,
[`city_${prop}`]: 'New York'
};
// { name: 'John', age: 30, city_name: 'New York' }
Getters and Setters
let person = {
firstName: 'John',
lastName: 'Doe',
get fullName() {
return `${this.firstName} ${this.lastName}`;
},
set fullName(name) {
let parts = name.split(' ');
this.firstName = parts[0];
this.lastName = parts[1];
}
};
console.log(person.fullName); // 'John Doe'
person.fullName = 'Jane Smith';
console.log(person.firstName); // 'Jane'
console.log(person.lastName); // 'Smith'
Prototypes and Inheritance
Prototype Chain
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
return `Hello, I'm ${this.name}`;
};
let john = new Person('John');
console.log(john.greet()); // 'Hello, I'm John'
// Check prototype
console.log(john.__proto__ === Person.prototype); // true
console.log(Person.prototype.__proto__ === Object.prototype); // true
Object.setPrototypeOf()
let animal = {
eats: true,
walk: function() {
console.log('Animal walks');
}
};
let dog = {
barks: true
};
Object.setPrototypeOf(dog, animal);
console.log(dog.eats); // true
dog.walk(); // 'Animal walks'
JSON and Objects
Converting to JSON
let person = { name: 'John', age: 30 };
let jsonString = JSON.stringify(person); // '{"name":"John","age":30}'
Parsing JSON
let jsonString = '{"name":"John","age":30}';
let person = JSON.parse(jsonString); // { name: 'John', age: 30 }
Object Comparison
let obj1 = { name: 'John' };
let obj2 = { name: 'John' };
let obj3 = obj1;
console.log(obj1 === obj2); // false (different objects)
console.log(obj1 === obj3); // true (same reference)
// Deep comparison
function deepEqual(a, b) {
if (a === b) return true;
if (a == null || typeof a != "object" ||
b == null || typeof b != "object") return false;
let keysA = Object.keys(a), keysB = Object.keys(b);
if (keysA.length != keysB.length) return false;
for (let key of keysA) {
if (!keysB.includes(key) || !deepEqual(a[key], b[key])) return false;
}
return true;
}
console.log(deepEqual(obj1, obj2)); // true
Common Patterns
Factory Function
function createPerson(name, age) {
return {
name,
age,
greet() {
return `Hello, I'm ${this.name}`;
}
};
}
let john = createPerson('John', 30);
Module Pattern
let counter = (function() {
let count = 0;
return {
increment: function() {
count++;
return count;
},
decrement: function() {
count--;
return count;
},
getCount: function() {
return count;
}
};
})();
console.log(counter.increment()); // 1
console.log(counter.getCount()); // 1
Mixins
let canEat = {
eat: function(food) {
return `${this.name} eats ${food}`;
}
};
let canWalk = {
walk: function() {
return `${this.name} walks`;
}
};
function Person(name) {
this.name = name;
}
Object.assign(Person.prototype, canEat, canWalk);
let john = new Person('John');
console.log(john.eat('pizza')); // 'John eats pizza'
console.log(john.walk()); // 'John walks'
Best Practices
Use Object Literals for Simple Objects
// Good
let config = {
apiUrl: 'https://api.example.com',
timeout: 5000,
retries: 3
};
Avoid Modifying Built-in Prototypes
// Bad - Don't do this
Array.prototype.sum = function() {
return this.reduce((a, b) => a + b, 0);
};
// Good - Create utility functions
function sumArray(arr) {
return arr.reduce((a, b) => a + b, 0);
}
Use Meaningful Property Names
// Good
let user = {
firstName: 'John',
lastName: 'Doe',
emailAddress: 'john@example.com'
};
// Avoid
let u = {
fn: 'John',
ln: 'Doe',
e: 'john@example.com'
};
Prefer const for Object References
const person = { name: 'John' };
person.name = 'Jane'; // OK - modifying property
person = {}; // Error - reassigning reference
Use Object Destructuring
// Good
function processUser({ name, age, email }) {
console.log(`${name} (${age}) - ${email}`);
}
// Avoid
function processUser(user) {
console.log(`${user.name} (${user.age}) - ${user.email}`);
}
Objects are incredibly versatile in JavaScript. Understanding how to create, manipulate, and work with objects is essential for building complex applications.
