In JavaScript, objects are collections of key-value pairs used to represent entities with properties and behaviors:
let user = {
name: "Chaoyang",
greet() {
console.log("Hello!");
}
};
Memory Representation
Objects are stored in heap memory. Variables hold references (memory addresses) to these heap-allocated objects, not the objects themselves.
Accessors: Getters and Setters
Custom logic can be attached to property access or assignment using getter and setter methods defined via get and set keywords within object literals or Object.defineProperty().
Object Creation Methods
1. Object Literal (Most Common)
let empty = {};
let profile = {
username: "chaoyang",
introduce() {
console.log(`Hi, I'm ${this.username}`);
}
};
ES6 enhancements include shorthand property names (username instead of username: username) and concise method syntax.
Dynamic keys are supported using bracket notation:
let category = "book";
let item = {
[`${category}Title`]: "Biography of Chaoyang",
[`${category}Promo`]() {
console.log("Free giveaway!");
}
};
2. Constructor Functions
Built-in:
let obj = new Object(); // Equivalent to {}
User-defined:
function User(name) {
this.name = name;
}
let me = new User("Chaoyang");
3. Object.create()
Creates an object with a specified prototype:
let protoObj = { shared: true };
let instance = Object.create(protoObj);
// Prototype chain: Object.prototype → protoObj → instance
// Null prototype (no inherited properties)
let cleanObj = Object.create(null);
Properties can be defined with descriptors as the second argument:
let person = Object.create(Object.prototype, {
name: { value: "Chaoyang", writable: true },
age: { value: 35, writable: true }
});
4. ES6 Classes
Syntactic sugar over constructor functions:
class Vehicle {
constructor(model, year) {
this.model = model;
this.year = year;
}
}
const car = new Vehicle("Fiesta", "2010");
5. Factory Functions
Return configured objects:
function createUser(name) {
return { name };
}
let user = createUser("Chaoyang");
Property Access and Modification
Use dot notation for static keys and bracket notation for dynamic keys:
obj.age = 35;
let key = "hobby";
obj[key] = "coding";
Accessing non-existent properties returns undefined. Inside methods, this refers to the object itself.
Enumeration and Inspection
Object.keys(obj)→ array of own enumerable string-keyed property namesObject.values(obj)→ array of corresponding valuesfor...inloop iterates over all enumerable properties in the prototype chain (usehasOwnProperty()to restrict to own properties)
Merging Objects
Object.assign(target, ...sources) performs shallow merging:
let base = { role: "admin" };
Object.assign(base, { level: 5 }, { active: true });
// base becomes { role: "admin", level: 5, active: true }
Note: This mutates the target object.
Copying Objects
Shallow Copy: Shares nested object references.
let original = { data: { id: 1 } };
let copy = { ...original };
// Modifying copy.data affects original.data
Deep Copy: Creates fully independent clones. A common approach uses serialization:
let deepCopy = JSON.parse(JSON.stringify(original));
Limitations: Fails with functions, undefined, Symbol, Date, RegExp, and circular references.
Utility Patterns
Check for Empty Object:
function isEmpty(obj) {
return Object.keys(obj).length === 0 && obj.constructor === Object;
}
Object Difference Detection: For complex comparisons, libraries like deep-diff or custom recursive algorithms are recommended over basic equality checks.