Skip to content

JavaScript Objects

JavaScript objects are one of the core concepts of the language. They are a composite data type used to store collections of key-value pairs and more complex entities. Objects are one of the most powerful features in JavaScript, and almost all JavaScript values (except primitives) are objects. In this chapter, we will learn in depth about various aspects of JavaScript objects.

What is an Object

An object is a collection of properties, where each property has a key (also called property name) and a value. Values can be primitive values (such as strings, numbers, booleans) or other objects, or even functions (called methods).

javascript
// Create a simple object
const person = {
    name: "John",
    age: 25,
    isStudent: true
};

Ways to Create Objects

javascript
const person = {
    name: "John",
    age: 25,
    greet: function() {
        return "Hello, I'm " + this.name;
    }
};

2. Using new Object()

javascript
const person = new Object();
person.name = "Jane";
person.age = 30;
person.greet = function() {
    return "Hello, I'm " + this.name;
};

3. Using Constructor Function

javascript
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.greet = function() {
        return "Hello, I'm " + this.name;
    };
}

const person1 = new Person("Alice", 28);

4. Using Object.create()

javascript
const personPrototype = {
    greet: function() {
        return "Hello, I'm " + this.name;
    }
};

const person = Object.create(personPrototype);
person.name = "Bob";
person.age = 35;

Accessing and Setting Properties

Dot Notation

javascript
const person = {
    name: "John",
    age: 25
};

// Access properties
console.log(person.name); // "John"
console.log(person.age);  // 25

// Set properties
person.age = 26;
person.city = "New York"; // Add new property

Bracket Notation

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

// Access properties
console.log(person["name"]); // "Jane"
console.log(person["age"]);  // 30

// Set properties
person["age"] = 31;
person["city"] = "Los Angeles"; // Add new property

// Dynamic property names
const propertyName = "hobby";
person[propertyName] = "reading";

Special Property Names

javascript
const obj = {
    "first name": "John",
    "last-name": "Doe",
    123: "numeric key",
    true: "boolean key"
};

console.log(obj["first name"]); // "John"
console.log(obj["last-name"]);  // "Doe"
console.log(obj[123]);          // "numeric key"
console.log(obj[true]);         // "boolean key"

Deleting Properties

javascript
const person = {
    name: "John",
    age: 25,
    city: "New York"
};

// Delete property
delete person.city;
console.log(person.city); // undefined

// Deleting non-existent property doesn't throw error
delete person.nonExistent; // Returns true

Object Methods

Functions in objects are called methods:

javascript
const calculator = {
    add: function(a, b) {
        return a + b;
    },
    
    subtract: function(a, b) {
        return a - b;
    },
    
    // ES6 shorthand method
    multiply(a, b) {
        return a * b;
    },
    
    divide(a, b) {
        if (b !== 0) {
            return a / b;
        } else {
            return "Cannot divide by zero";
        }
    }
};

console.log(calculator.add(5, 3));      // 8
console.log(calculator.multiply(4, 2));  // 8

The this Keyword

In object methods, the this keyword refers to the object that called the method:

javascript
const person = {
    name: "John",
    age: 25,
    
    introduce: function() {
        return "I'm " + this.name + ", " + this.age + " years old";
    },
    
    growOlder: function() {
        this.age++;
        return this.age;
    }
};

console.log(person.introduce()); // "I'm John, 25 years old"
console.log(person.growOlder()); // 26

Iterating Over Objects

for...in Loop

javascript
const person = {
    name: "John",
    age: 25,
    city: "New York"
};

for (let key in person) {
    console.log(key + ": " + person[key]);
}
// Output:
// name: John
// age: 25
// city: New York

Object.keys()

javascript
const person = {
    name: "Jane",
    age: 30,
    city: "Los Angeles"
};

const keys = Object.keys(person);
console.log(keys); // ["name", "age", "city"]

keys.forEach(key => {
    console.log(key + ": " + person[key]);
});

Object.values()

javascript
const person = {
    name: "Alice",
    age: 28,
    city: "Chicago"
};

const values = Object.values(person);
console.log(values); // ["Alice", 28, "Chicago"]

Object.entries()

javascript
const person = {
    name: "Bob",
    age: 35,
    city: "Miami"
};

const entries = Object.entries(person);
console.log(entries); 
// [["name", "Bob"], ["age", 35], ["city", "Miami"]]

entries.forEach(([key, value]) => {
    console.log(key + ": " + value);
});

Property Descriptors

JavaScript allows fine-grained control over object properties:

javascript
const obj = {};

// Define property
Object.defineProperty(obj, "name", {
    value: "John",
    writable: false,    // Not writable
    enumerable: true,   // Enumerable
    configurable: false // Not configurable
});

console.log(obj.name); // "John"
obj.name = "Jane";     // Invalid, but throws error in strict mode
console.log(obj.name); // Still "John"

Freezing and Sealing Objects

Object.freeze()

javascript
const obj = {
    name: "John",
    age: 25
};

Object.freeze(obj);

// All these operations are invalid
obj.age = 30;        // Invalid
obj.city = "NYC";    // Invalid
delete obj.name;     // Invalid

console.log(obj); // { name: "John", age: 25 }

Object.seal()

javascript
const obj = {
    name: "Jane",
    age: 30
};

Object.seal(obj);

// Can modify existing properties
obj.age = 31;        // Valid

// But cannot add or delete properties
obj.city = "LA";     // Invalid
delete obj.name;     // Invalid

console.log(obj); // { name: "Jane", age: 31 }

Nested Objects

Objects can contain other objects:

javascript
const company = {
    name: "Tech Corp",
    address: {
        street: "123 Main St",
        city: "New York",
        zipCode: "10001"
    },
    employees: [
        {
            name: "John",
            position: "Engineer",
            contact: {
                email: "john@example.com",
                phone: "123-456-7890"
            }
        },
        {
            name: "Jane",
            position: "Designer",
            contact: {
                email: "jane@example.com",
                phone: "098-765-4321"
            }
        }
    ]
};

// Access nested properties
console.log(company.address.city); // "New York"
console.log(company.employees[0].contact.email); // "john@example.com"

Object Copying

Shallow Copy

javascript
const original = {
    name: "John",
    age: 25,
    hobbies: ["reading", "swimming"]
};

// Using Object.assign()
const copy1 = Object.assign({}, original);

// Using spread operator (ES6)
const copy2 = { ...original };

// Problem with shallow copy: nested objects are still references
copy1.name = "Jane";
copy1.hobbies.push("running");

console.log(original.name);    // "John" (unchanged)
console.log(original.hobbies); // ["reading", "swimming", "running"] (changed!)

Deep Copy

javascript
const original = {
    name: "John",
    age: 25,
    hobbies: ["reading", "swimming"],
    address: {
        city: "New York",
        street: "Main St"
    }
};

// Using JSON methods (with limitations)
const deepCopy = JSON.parse(JSON.stringify(original));

deepCopy.name = "Jane";
deepCopy.hobbies.push("running");
deepCopy.address.city = "Los Angeles";

console.log(original.name);     // "John" (unchanged)
console.log(original.hobbies);  // ["reading", "swimming"] (unchanged)
console.log(original.address.city); // "New York" (unchanged)

// Note: JSON methods cannot copy functions, undefined, Symbol, etc.

Object Merging

javascript
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const obj3 = { c: 5, d: 6 };

// Using Object.assign()
const merged1 = Object.assign({}, obj1, obj2, obj3);
console.log(merged1); // { a: 1, b: 3, c: 5, d: 6 }

// Using spread operator
const merged2 = { ...obj1, ...obj2, ...obj3 };
console.log(merged2); // { a: 1, b: 3, c: 5, d: 6 }

Object Destructuring

javascript
const person = {
    name: "John",
    age: 25,
    city: "New York",
    job: "Engineer"
};

// Basic destructuring
const { name, age } = person;
console.log(name); // "John"
console.log(age);  // 25

// Renaming variables
const { name: fullName, age: years } = person;
console.log(fullName); // "John"
console.log(years);    // 25

// Default values
const { name: n, salary = 5000 } = person;
console.log(n);      // "John"
console.log(salary); // 5000

// Nested destructuring
const company = {
    name: "Tech Corp",
    address: {
        city: "New York",
        street: "Main St"
    }
};

const { address: { city } } = company;
console.log(city); // "New York"

Computed Property Names

javascript
const propertyName = "dynamicProperty";
const value = "dynamic value";

// ES6 computed property names
const obj = {
    [propertyName]: value,
    [1 + 2]: "computed result"
};

console.log(obj.dynamicProperty); // "dynamic value"
console.log(obj[3]);              // "computed result"

Object Methods

Object.keys(), Object.values(), Object.entries()

javascript
const person = {
    name: "John",
    age: 25,
    city: "New York"
};

console.log(Object.keys(person));    // ["name", "age", "city"]
console.log(Object.values(person));  // ["John", 25, "New York"]
console.log(Object.entries(person)); // [["name", "John"], ["age", 25], ["city", "New York"]]

Object.hasOwnProperty()

javascript
const person = {
    name: "John",
    age: 25
};

console.log(person.hasOwnProperty("name"));     // true
console.log(person.hasOwnProperty("toString")); // false

Object.is()

javascript
console.log(Object.is(1, 1));        // true
console.log(Object.is(0, -0));       // false
console.log(Object.is(NaN, NaN));    // true
console.log(Object.is(null, null));  // true

Practical Example

javascript
// User management system
const userSystem = {
    users: [],
    
    addUser(user) {
        this.users.push({
            id: Date.now(),
            ...user,
            createdAt: new Date()
        });
    },
    
    findUserById(id) {
        return this.users.find(user => user.id === id);
    },
    
    updateUser(id, updates) {
        const user = this.findUserById(id);
        if (user) {
            Object.assign(user, updates);
            return user;
        }
        return null;
    },
    
    deleteUser(id) {
        const index = this.users.findIndex(user => user.id === id);
        if (index !== -1) {
            return this.users.splice(index, 1)[0];
        }
        return null;
    },
    
    listUsers() {
        return this.users.map(user => ({
            id: user.id,
            name: user.name,
            email: user.email
        }));
    }
};

// Usage example
userSystem.addUser({ name: "John", email: "john@example.com" });
userSystem.addUser({ name: "Jane", email: "jane@example.com" });

console.log(userSystem.listUsers());

Summary

Key points about JavaScript objects:

  1. Creation Methods: Object literal, new Object(), constructor function, Object.create()
  2. Property Access: Dot notation, bracket notation
  3. Method Definition: Regular function, ES6 shorthand method
  4. this Keyword: Refers to the calling object
  5. Iteration Methods: for...in, Object.keys(), Object.values(), Object.entries()
  6. Property Control: Property descriptors, freeze, seal
  7. Copy Operations: Shallow copy, deep copy
  8. Modern Features: Destructuring, spread operator, computed property names

Objects are the foundation of JavaScript programming, and mastering their use is crucial for writing complex JavaScript applications. In the next chapter, we will learn about JavaScript conditional statements.

Content is for learning and research only.