# JavaScript Object Methods Complete Guide
Master Object static methods, property operations, object traversal, and practical techniques
Objects are the core data structure in JavaScript. This article covers various methods and techniques for object manipulation.
Creating Objects
Basic Methods
// Literal (most common)
const obj = { name: 'Alice', age: 25 };
// Constructor
const obj2 = new Object();
obj2.name = 'Bob';
// Object.create (specify prototype)
const proto = { greet() { return `Hello, ${this.name}`; } };
const obj3 = Object.create(proto);
obj3.name = 'Charlie';
obj3.greet(); // 'Hello, Charlie'
// Object.create(null) (no prototype)
const pureObj = Object.create(null);
// pureObj.toString // undefined
Object.assign
// Merge objects
const target = { a: 1 };
const source = { b: 2, c: 3 };
Object.assign(target, source);
// target = { a: 1, b: 2, c: 3 }
// Merge multiple objects
const merged = Object.assign({}, obj1, obj2, obj3);
// Shallow copy
const copy = Object.assign({}, original);
// Later properties override earlier ones
const defaults = { host: 'localhost', port: 3000 };
const options = { port: 8080 };
const config = Object.assign({}, defaults, options);
// { host: 'localhost', port: 8080 }
// Note: Only copies enumerable own properties
Object.fromEntries
// Create object from key-value pair array
const entries = [['name', 'Alice'], ['age', 25]];
const obj = Object.fromEntries(entries);
// { name: 'Alice', age: 25 }
// Create object from Map
const map = new Map([['a', 1], ['b', 2]]);
const fromMap = Object.fromEntries(map);
// { a: 1, b: 2 }
// Transform object with Object.entries
const original = { a: 1, b: 2, c: 3 };
const doubled = Object.fromEntries(
Object.entries(original).map(([k, v]) => [k, v * 2])
);
// { a: 2, b: 4, c: 6 }
Property Operations
Property Access
const obj = { name: 'Alice', 'full-name': 'Alice Smith' };
// Dot notation
obj.name; // 'Alice'
// Bracket notation (supports dynamic keys)
obj['name']; // 'Alice'
obj['full-name']; // 'Alice Smith'
const key = 'name';
obj[key]; // 'Alice'
// Optional chaining
const user = { address: { city: 'NYC' } };
user?.address?.city; // 'NYC'
user?.contact?.email; // undefined (no error)
Property Checking
const obj = { name: 'Alice', age: 25 };
// in operator (includes inherited)
'name' in obj; // true
'toString' in obj; // true
// hasOwnProperty (own properties only)
obj.hasOwnProperty('name'); // true
obj.hasOwnProperty('toString'); // false
// Object.hasOwn (ES2022, recommended)
Object.hasOwn(obj, 'name'); // true
Object.hasOwn(obj, 'toString'); // false
// Checking property value
obj.email !== undefined; // Unreliable
'email' in obj; // Reliable
Property Definition
const obj = {};
// Object.defineProperty (single property)
Object.defineProperty(obj, 'name', {
value: 'Alice',
writable: true, // Can be changed
enumerable: true, // Shows in enumeration
configurable: true // Can be configured
});
// Object.defineProperties (multiple properties)
Object.defineProperties(obj, {
name: {
value: 'Alice',
writable: true
},
age: {
value: 25,
writable: false // Read-only
}
});
// getter and setter
Object.defineProperty(obj, 'fullName', {
get() {
return `${this.firstName} ${this.lastName}`;
},
set(value) {
[this.firstName, this.lastName] = value.split(' ');
}
});
Property Descriptors
const obj = { name: 'Alice' };
// Get single property descriptor
Object.getOwnPropertyDescriptor(obj, 'name');
// { value: 'Alice', writable: true, enumerable: true, configurable: true }
// Get all property descriptors
Object.getOwnPropertyDescriptors(obj);
// { name: { value: 'Alice', writable: true, ... } }
// Complete object copy (including descriptors)
const clone = Object.defineProperties(
{},
Object.getOwnPropertyDescriptors(original)
);
Object Traversal
Object.keys / values / entries
const obj = { a: 1, b: 2, c: 3 };
// Get keys array
Object.keys(obj); // ['a', 'b', 'c']
// Get values array
Object.values(obj); // [1, 2, 3]
// Get key-value pair array
Object.entries(obj); // [['a', 1], ['b', 2], ['c', 3]]
// Iterate object
Object.entries(obj).forEach(([key, value]) => {
console.log(`${key}: ${value}`);
});
// Using for...of
for (const [key, value] of Object.entries(obj)) {
console.log(`${key}: ${value}`);
}
for…in Loop
const obj = { a: 1, b: 2 };
// for...in iteration (includes inherited enumerable)
for (const key in obj) {
console.log(key, obj[key]);
}
// Iterate own properties only
for (const key in obj) {
if (Object.hasOwn(obj, key)) {
console.log(key, obj[key]);
}
}
Getting Property Names
const sym = Symbol('id');
const obj = {
name: 'Alice',
[sym]: 123
};
Object.defineProperty(obj, 'hidden', {
value: 'secret',
enumerable: false
});
// Enumerable own properties
Object.keys(obj); // ['name']
// All own properties (including non-enumerable)
Object.getOwnPropertyNames(obj); // ['name', 'hidden']
// Symbol properties
Object.getOwnPropertySymbols(obj); // [Symbol(id)]
// All own properties (string + Symbol)
Reflect.ownKeys(obj); // ['name', 'hidden', Symbol(id)]
Object Protection
Object.freeze
const obj = { name: 'Alice', address: { city: 'NYC' } };
// Freeze object (no modify, add, delete)
Object.freeze(obj);
obj.name = 'Bob'; // Silently fails (error in strict mode)
obj.age = 25; // Won't add
delete obj.name; // Won't delete
console.log(obj.name); // 'Alice'
// Check if frozen
Object.isFrozen(obj); // true
// Note: Shallow freeze
obj.address.city = 'LA'; // Still modifiable
console.log(obj.address.city); // 'LA'
// Deep freeze function
function deepFreeze(obj) {
Object.freeze(obj);
Object.values(obj).forEach(value => {
if (typeof value === 'object' && value !== null) {
deepFreeze(value);
}
});
return obj;
}
Object.seal
const obj = { name: 'Alice' };
// Seal object (can modify, no add/delete)
Object.seal(obj);
obj.name = 'Bob'; // OK
obj.age = 25; // Won't add
delete obj.name; // Won't delete
// Check if sealed
Object.isSealed(obj); // true
Object.preventExtensions
const obj = { name: 'Alice' };
// Prevent extensions (can modify/delete, no add)
Object.preventExtensions(obj);
obj.name = 'Bob'; // OK
delete obj.name; // OK
obj.age = 25; // Won't add
// Check if extensible
Object.isExtensible(obj); // false
Protection Level Comparison
Object Protection Levels:
┌─────────────────────────────────────────────────────┐
│ │
│ Method Add Delete Modify Config │
│ ├── preventExtensions ✗ ✓ ✓ ✓ │
│ ├── seal ✗ ✗ ✓ ✗ │
│ └── freeze ✗ ✗ ✗ ✗ │
│ │
└─────────────────────────────────────────────────────┘
Object Comparison
Equality Checking
// Object.is (strict equality, handles edge cases)
Object.is(1, 1); // true
Object.is(NaN, NaN); // true (=== is false)
Object.is(0, -0); // false (=== is true)
// === strict equality
1 === 1; // true
NaN === NaN; // false
0 === -0; // true
// Object reference comparison
const obj1 = { a: 1 };
const obj2 = { a: 1 };
obj1 === obj2; // false (different references)
const obj3 = obj1;
obj1 === obj3; // true (same reference)
Deep Comparison
// Simple deep comparison
function deepEqual(obj1, obj2) {
if (obj1 === obj2) return true;
if (typeof obj1 !== 'object' || typeof obj2 !== 'object') {
return false;
}
if (obj1 === null || obj2 === null) return false;
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);
if (keys1.length !== keys2.length) return false;
return keys1.every(key =>
Object.hasOwn(obj2, key) && deepEqual(obj1[key], obj2[key])
);
}
// Usage
deepEqual({ a: 1, b: { c: 2 } }, { a: 1, b: { c: 2 } }); // true
Practical Techniques
Object Destructuring
const user = { name: 'Alice', age: 25, city: 'NYC' };
// Basic destructuring
const { name, age } = user;
// Renaming
const { name: userName } = user;
// Default values
const { country = 'USA' } = user;
// Rest properties
const { name, ...rest } = user;
// rest = { age: 25, city: 'NYC' }
Conditional Properties
const condition = true;
// Conditionally add properties
const obj = {
always: true,
...(condition && { sometimes: true })
};
// Or use ternary
const obj2 = {
...(condition ? { a: 1 } : { b: 2 })
};
Dynamic Key Names
const key = 'name';
const value = 'Alice';
// Computed property names
const obj = {
[key]: value,
[`${key}Length`]: value.length
};
// { name: 'Alice', nameLength: 5 }
Object Method Shorthand
// ES6 method shorthand
const obj = {
name: 'Alice',
// Method shorthand
greet() {
return `Hello, ${this.name}`;
},
// getter/setter
get upperName() {
return this.name.toUpperCase();
},
set lowerName(value) {
this.name = value.toLowerCase();
}
};
Removing Properties
const obj = { a: 1, b: 2, c: 3 };
// delete operator
delete obj.a;
// Destructuring (doesn't modify original)
const { b, ...rest } = obj;
// rest = { a: 1, c: 3 }
// Filter multiple properties
const omit = (obj, keys) => Object.fromEntries(
Object.entries(obj).filter(([k]) => !keys.includes(k))
);
omit(obj, ['a', 'b']); // { c: 3 }
Best Practices Summary
Object Operation Best Practices:
┌─────────────────────────────────────────────────────┐
│ │
│ Creation and Copying │
│ ├── Prefer literal syntax for creation │
│ ├── Use spread operator for shallow copy │
│ └── Use structuredClone or libraries for deep │
│ │
│ Property Operations │
│ ├── Use Object.hasOwn to check own properties │
│ ├── Use optional chaining for safe nested access │
│ └── Use destructuring to simplify extraction │
│ │
│ Traversal Choices │
│ ├── Object.keys/values/entries most common │
│ ├── Avoid for...in (includes inherited) │
│ └── Reflect.ownKeys gets all keys │
│ │
└─────────────────────────────────────────────────────┘
| Method | Purpose | Returns |
|---|---|---|
| Object.keys | Get keys | String array |
| Object.values | Get values | Value array |
| Object.entries | Get key-value pairs | 2D array |
| Object.assign | Merge objects | Target object |
Master object methods to efficiently manipulate JavaScript data structures.