Docs

10.4-Object-Static-Methods

7.4 Object Static Methods

Table of Contents

  1. •Introduction
  2. •Object Creation Methods
  3. •Property Enumeration Methods
  4. •Object Manipulation Methods
  5. •Object Inspection Methods
  6. •Object Protection Methods
  7. •Prototype Methods
  8. •Modern Object Methods
  9. •Method Comparison Tables
  10. •Best Practices

Introduction

JavaScript's Object constructor provides many static methods that operate on objects. These are called on Object itself, not on object instances.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│              Object Static Methods Categories                │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                             │
│  Creation         ──────►  Object.create()                  │
│                            Object.assign()                  │
│                            Object.fromEntries()             │
│                                                             │
│  Enumeration      ──────►  Object.keys()                    │
│                            Object.values()                  │
│                            Object.entries()                 │
│                                                             │
│  Inspection       ──────►  Object.is()                      │
│                            Object.hasOwn()                  │
│                            Object.getOwnPropertyNames()     │
│                                                             │
│  Protection       ──────►  Object.freeze()                  │
│                            Object.seal()                    │
│                            Object.preventExtensions()       │
│                                                             │
│  Prototype        ──────►  Object.getPrototypeOf()          │
│                            Object.setPrototypeOf()          │
│                                                             │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Object Creation Methods

Object.create()

Creates a new object with the specified prototype and optional property descriptors.

// Create object with specific prototype
const personProto = {
  greet() {
    return `Hello, I'm ${this.name}`;
  },
};

const person = Object.create(personProto);
person.name = 'Alice';
console.log(person.greet()); // "Hello, I'm Alice"

// Create object with null prototype (no inherited properties)
const pureDict = Object.create(null);
pureDict.key = 'value';
console.log(pureDict.toString); // undefined (no Object.prototype)

// Create object with property descriptors
const config = Object.create(null, {
  apiUrl: {
    value: 'https://api.example.com',
    writable: false,
    enumerable: true,
  },
  timeout: {
    value: 5000,
    writable: true,
    enumerable: true,
  },
});

Object.assign()

Copies enumerable own properties from source objects to a target object.

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    Object.assign() Flow                            │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                   │
│   target          source1         source2                         │
│   ā”Œā”€ā”€ā”€ā”€ā”€ā”         ā”Œā”€ā”€ā”€ā”€ā”€ā”         ā”Œā”€ā”€ā”€ā”€ā”€ā”                         │
│   │ a:1 │   ←──   │ b:2 │   ←──   │ c:3 │                         │
│   ā””ā”€ā”€ā”€ā”€ā”€ā”˜         ā””ā”€ā”€ā”€ā”€ā”€ā”˜         │ b:9 │                         │
│                                   ā””ā”€ā”€ā”€ā”€ā”€ā”˜                         │
│                                                                   │
│   Result: { a:1, b:9, c:3 }  (later sources override)             │
│                                                                   │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
// Basic usage
const target = { a: 1 };
const source = { b: 2, c: 3 };
const result = Object.assign(target, source);
console.log(result); // { a: 1, b: 2, c: 3 }
console.log(target === result); // true (mutates target)

// Multiple sources (later overrides earlier)
const combined = Object.assign({}, { a: 1, b: 1 }, { b: 2, c: 2 }, { c: 3 });
console.log(combined); // { a: 1, b: 2, c: 3 }

// Shallow copy
const original = { nested: { x: 1 } };
const copy = Object.assign({}, original);
copy.nested.x = 99;
console.log(original.nested.x); // 99 (same nested object!)

Object.fromEntries()

Creates an object from an array of key-value pairs (inverse of Object.entries()).

// From entries array
const entries = [
  ['name', 'Alice'],
  ['age', 30],
];
const obj = Object.fromEntries(entries);
console.log(obj); // { name: "Alice", age: 30 }

// From Map
const map = new Map([
  ['x', 1],
  ['y', 2],
]);
const fromMap = Object.fromEntries(map);
console.log(fromMap); // { x: 1, y: 2 }

// Transform object properties
const prices = { apple: 1.5, banana: 0.75, cherry: 2.0 };
const doubled = Object.fromEntries(
  Object.entries(prices).map(([key, value]) => [key, value * 2])
);
console.log(doubled); // { apple: 3, banana: 1.5, cherry: 4 }

Property Enumeration Methods

Object.keys()

Returns an array of object's own enumerable property names.

const user = {
  name: 'Alice',
  age: 30,
  email: 'alice@example.com',
};

console.log(Object.keys(user));
// ["name", "age", "email"]

// Only own properties
const child = Object.create({ inherited: true });
child.own = 'property';
console.log(Object.keys(child)); // ["own"]

Object.values()

Returns an array of object's own enumerable property values.

const user = {
  name: 'Alice',
  age: 30,
  email: 'alice@example.com',
};

console.log(Object.values(user));
// ["Alice", 30, "alice@example.com"]

// Practical use: sum values
const scores = { math: 95, english: 87, science: 92 };
const total = Object.values(scores).reduce((sum, v) => sum + v, 0);
console.log(total); // 274

Object.entries()

Returns an array of object's own enumerable [key, value] pairs.

const user = {
  name: 'Alice',
  age: 30,
};

console.log(Object.entries(user));
// [["name", "Alice"], ["age", 30]]

// Iterate with destructuring
for (const [key, value] of Object.entries(user)) {
  console.log(`${key}: ${value}`);
}

// Convert to Map
const map = new Map(Object.entries(user));
console.log(map.get('name')); // "Alice"

Object.getOwnPropertyNames()

Returns ALL own property names, including non-enumerable ones.

const obj = { visible: true };
Object.defineProperty(obj, 'hidden', {
  value: 'secret',
  enumerable: false,
});

console.log(Object.keys(obj));
// ["visible"]

console.log(Object.getOwnPropertyNames(obj));
// ["visible", "hidden"]

Object.getOwnPropertySymbols()

Returns all own Symbol property keys.

const sym1 = Symbol('id');
const sym2 = Symbol('secret');

const obj = {
  name: 'Object',
  [sym1]: 12345,
  [sym2]: 'hidden',
};

console.log(Object.keys(obj)); // ["name"]
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(id), Symbol(secret)]

Object Manipulation Methods

Reflect.ownKeys()

Returns ALL own property keys (strings AND symbols).

const sym = Symbol('key');
const obj = {
  normal: 'value',
  [sym]: 'symbol value',
};

Object.defineProperty(obj, 'hidden', {
  value: 'non-enumerable',
  enumerable: false,
});

console.log(Reflect.ownKeys(obj));
// ["normal", "hidden", Symbol(key)]

Object.getOwnPropertyDescriptor()

Returns the property descriptor for a specific property.

const obj = { name: 'Alice' };

const descriptor = Object.getOwnPropertyDescriptor(obj, 'name');
console.log(descriptor);
/*
{
    value: "Alice",
    writable: true,
    enumerable: true,
    configurable: true
}
*/

Object.getOwnPropertyDescriptors()

Returns descriptors for ALL own properties.

const obj = {
  name: 'Alice',
  get fullName() {
    return this.name;
  },
};

console.log(Object.getOwnPropertyDescriptors(obj));
/*
{
    name: {
        value: "Alice",
        writable: true,
        enumerable: true,
        configurable: true
    },
    fullName: {
        get: [Function: get fullName],
        set: undefined,
        enumerable: true,
        configurable: true
    }
}
*/

Object Inspection Methods

Object.is()

Compares two values for sameness (similar to === but handles edge cases).

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                 Object.is() vs === vs ==                           │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│   Comparison     │  Object.is() │     ===     │        ==         │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│  NaN === NaN     │    true      │    false    │      false        │
│  +0 === -0       │    false     │    true     │      true         │
│  5 === 5         │    true      │    true     │      true         │
│  "5" === 5       │    false     │    false    │      true         │
│  null === undef  │    false     │    false    │      true         │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”“ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
// NaN handling
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true

// Signed zero handling
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false

// Regular equality
console.log(Object.is(5, 5)); // true
console.log(Object.is({}, {})); // false (different objects)

Object.hasOwn() (ES2022)

Checks if object has specified own property (preferred over hasOwnProperty).

const user = {
  name: 'Alice',
  hasOwnProperty: 'overridden!', // Common gotcha
};

// Safe check with Object.hasOwn()
console.log(Object.hasOwn(user, 'name')); // true
console.log(Object.hasOwn(user, 'toString')); // false (inherited)

// Object.prototype.hasOwnProperty can break
// console.log(user.hasOwnProperty("name"));  // Error!

Object.prototype.isPrototypeOf()

Checks if an object exists in another object's prototype chain.

const animal = { eats: true };
const dog = Object.create(animal);

console.log(animal.isPrototypeOf(dog)); // true
console.log(Object.prototype.isPrototypeOf(dog)); // true

Object Protection Methods

Object.freeze()

Makes object completely immutable (no changes allowed).

const frozen = Object.freeze({
  name: 'Frozen',
  data: { x: 1 },
});

frozen.name = 'Changed'; // Silently fails
frozen.newProp = 'new'; // Silently fails
delete frozen.name; // Silently fails

console.log(frozen); // { name: "Frozen", data: { x: 1 } }

// WARNING: Nested objects are NOT frozen
frozen.data.x = 999;
console.log(frozen.data.x); // 999

Object.seal()

Prevents adding/removing properties but allows modifying values.

const sealed = Object.seal({
  name: 'Sealed',
  count: 0,
});

sealed.count = 100; // Works!
sealed.newProp = 'new'; // Silently fails
delete sealed.name; // Silently fails

console.log(sealed); // { name: "Sealed", count: 100 }

Object.preventExtensions()

Prevents adding new properties only.

const limited = Object.preventExtensions({
  existing: 'value',
});

limited.existing = 'modified'; // Works
limited.newProp = 'new'; // Silently fails
delete limited.existing; // Works!

console.log(Object.isExtensible(limited)); // false

Protection Check Methods

const obj = { x: 1 };

Object.freeze(obj);

console.log(Object.isFrozen(obj)); // true
console.log(Object.isSealed(obj)); // true (frozen implies sealed)
console.log(Object.isExtensible(obj)); // false

Prototype Methods

Object.getPrototypeOf()

Returns the prototype of an object.

const arr = [1, 2, 3];
console.log(Object.getPrototypeOf(arr) === Array.prototype); // true

const obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true

const nullProto = Object.create(null);
console.log(Object.getPrototypeOf(nullProto)); // null

Object.setPrototypeOf()

Sets the prototype of an object (use sparingly - performance impact).

const animal = {
  speak() {
    console.log('Some sound');
  },
};

const dog = {
  bark() {
    console.log('Woof!');
  },
};

Object.setPrototypeOf(dog, animal);
dog.speak(); // "Some sound"
dog.bark(); // "Woof!"

// āš ļø Warning: setPrototypeOf is slow, prefer Object.create()

Modern Object Methods

Object.groupBy() (ES2024)

Groups elements by a key returned from a callback.

const people = [
  { name: 'Alice', age: 25, department: 'Engineering' },
  { name: 'Bob', age: 30, department: 'Marketing' },
  { name: 'Charlie', age: 28, department: 'Engineering' },
];

const byDepartment = Object.groupBy(people, (person) => person.department);
console.log(byDepartment);
/*
{
    Engineering: [
        { name: "Alice", age: 25, department: "Engineering" },
        { name: "Charlie", age: 28, department: "Engineering" }
    ],
    Marketing: [
        { name: "Bob", age: 30, department: "Marketing" }
    ]
}
*/

Method Comparison Tables

Property Access Methods

MethodEnumerableNon-EnumerableSymbolsInherited
Object.keys()āœ“āœ—āœ—āœ—
Object.values()āœ“āœ—āœ—āœ—
Object.entries()āœ“āœ—āœ—āœ—
Object.getOwnPropertyNames()āœ“āœ“āœ—āœ—
Object.getOwnPropertySymbols()āœ—āœ—āœ“āœ—
Reflect.ownKeys()āœ“āœ“āœ“āœ—
for...ināœ“āœ—āœ—āœ“

Protection Levels

MethodAdd PropsDelete PropsModify ValuesReconfigure
Normal Objectāœ“āœ“āœ“āœ“
preventExtensions()āœ—āœ“āœ“āœ“
seal()āœ—āœ—āœ“āœ—
freeze()āœ—āœ—āœ—āœ—

Best Practices

1. Use Object.hasOwn() Instead of hasOwnProperty

// āœ“ Good - Safe
if (Object.hasOwn(obj, 'prop')) {
}

// āœ— Avoid - Can break if hasOwnProperty is overridden
if (obj.hasOwnProperty('prop')) {
}

2. Use Object.assign() for Shallow Merging

// āœ“ Good - Creates new object
const merged = Object.assign({}, defaults, userOptions);

// Alternative with spread (preferred for simple cases)
const merged = { ...defaults, ...userOptions };

3. Use Object.create(null) for Pure Dictionaries

// āœ“ Good - No prototype pollution risks
const cache = Object.create(null);
cache['__proto__'] = 'value'; // Actually sets the property

// āœ— Risk - Prototype pollution
const cache = {};
cache['__proto__'] = 'malicious'; // Modifies prototype!

4. Use Object.freeze() for Constants

const CONFIG = Object.freeze({
  API_URL: 'https://api.example.com',
  TIMEOUT: 5000,
});

5. Use Object.fromEntries() for Transformations

// Filter object properties
const filtered = Object.fromEntries(
  Object.entries(obj).filter(([key]) => !key.startsWith('_'))
);

// Transform values
const transformed = Object.fromEntries(
  Object.entries(obj).map(([key, val]) => [key, val.toUpperCase()])
);

Files in This Section

  • •README.md - This documentation
  • •examples.js - Runnable code examples
  • •exercises.js - Practice exercises with solutions

Navigation

.4 Object Static Methods - JavaScript Tutorial | DeepML