JavaScript ObjectsFeatured

JavaScript Object Methods: Complete Reference Guide

Master all JavaScript Object methods including Object.keys(), Object.values(), Object.entries(), Object.assign(), and more. Learn practical examples and best practices.

By JavaScript Document Team
objectsmethodses6object-manipulationreference

JavaScript provides numerous static methods on the Object constructor for working with objects. These methods are essential for object manipulation, property inspection, and implementing common patterns in JavaScript applications.

Object Property Enumeration

These methods help you work with object properties and their values.

Object.keys()

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

const person = {
  name: 'John',
  age: 30,
  city: 'New York',
};

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

// Only own properties (not inherited)
const student = Object.create(person);
student.grade = 'A';

console.log(Object.keys(student)); // ['grade'] only

// Non-enumerable properties are excluded
const obj = {};
Object.defineProperty(obj, 'hidden', {
  value: 'secret',
  enumerable: false,
});
obj.visible = 'public';

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

// Working with arrays
const arr = ['a', 'b', 'c'];
console.log(Object.keys(arr)); // ['0', '1', '2']

// Practical use: Iteration
Object.keys(person).forEach((key) => {
  console.log(`${key}: ${person[key]}`);
});

Object.values()

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

const product = {
  name: 'Laptop',
  price: 999,
  inStock: true,
};

const values = Object.values(product);
console.log(values); // ['Laptop', 999, true]

// Sum numeric values
const scores = {
  math: 95,
  english: 88,
  science: 92,
};

const total = Object.values(scores).reduce((sum, score) => sum + score, 0);
console.log(total); // 275

// Filter values
const inventory = {
  apples: 10,
  bananas: 0,
  oranges: 5,
  grapes: 0,
};

const inStock = Object.values(inventory).filter((count) => count > 0);
console.log(inStock); // [10, 5]

// Check if all values meet condition
const ages = {
  john: 25,
  jane: 30,
  bob: 28,
};

const allAdults = Object.values(ages).every((age) => age >= 18);
console.log(allAdults); // true

Object.entries()

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

const car = {
  make: 'Toyota',
  model: 'Camry',
  year: 2022,
};

const entries = Object.entries(car);
console.log(entries);
// [['make', 'Toyota'], ['model', 'Camry'], ['year', 2022]]

// Convert to Map
const carMap = new Map(Object.entries(car));
console.log(carMap.get('make')); // 'Toyota'

// Destructuring in loops
for (const [key, value] of Object.entries(car)) {
  console.log(`${key}: ${value}`);
}

// Transform object
const prices = {
  apple: 0.5,
  banana: 0.3,
  orange: 0.6,
};

const discountedPrices = Object.entries(prices).reduce(
  (acc, [fruit, price]) => {
    acc[fruit] = price * 0.9; // 10% discount
    return acc;
  },
  {}
);

console.log(discountedPrices);
// { apple: 0.45, banana: 0.27, orange: 0.54 }

// Filter and reconstruct object
const data = {
  a: 1,
  b: null,
  c: 3,
  d: undefined,
  e: 5,
};

const filtered = Object.fromEntries(
  Object.entries(data).filter(([key, value]) => value != null)
);
console.log(filtered); // { a: 1, c: 3, e: 5 }

Object.getOwnPropertyNames()

Returns all own property names (enumerable and non-enumerable).

const obj = {
  visible: 'yes',
};

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

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

// Array properties
const arr = ['a', 'b'];
console.log(Object.getOwnPropertyNames(arr)); // ['0', '1', 'length']

// Function properties
function myFunc() {}
myFunc.customProp = 'value';

console.log(Object.getOwnPropertyNames(myFunc));
// ['length', 'name', 'prototype', 'customProp'] (and others)

// Built-in object properties
console.log(Object.getOwnPropertyNames(Object.prototype));
// ['constructor', 'hasOwnProperty', 'toString', ...]

Object.getOwnPropertySymbols()

Returns all own symbol properties.

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

const obj = {
  [sym1]: 123,
  [sym2]: 'Test',
  regular: 'value',
};

console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(id), Symbol(name)]
console.log(Object.keys(obj)); // ['regular'] - symbols not included

// Accessing symbol properties
const symbols = Object.getOwnPropertySymbols(obj);
symbols.forEach((sym) => {
  console.log(obj[sym]);
});

// Combining all properties
function getAllKeys(obj) {
  return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
}

console.log(getAllKeys(obj)); // ['regular', Symbol(id), Symbol(name)]

Object Creation and Prototype

Methods for creating objects and working with prototypes.

Object.create()

Creates a new object with the specified prototype.

// Basic usage
const animal = {
  type: 'animal',
  speak() {
    console.log(`The ${this.type} makes a sound`);
  },
};

const dog = Object.create(animal);
dog.type = 'dog';
dog.speak(); // "The dog makes a sound"

// With property descriptors
const person = Object.create(null, {
  name: {
    value: 'John',
    writable: true,
    enumerable: true,
    configurable: true,
  },
  age: {
    value: 30,
    writable: false,
    enumerable: true,
    configurable: false,
  },
});

console.log(person.name); // 'John'
person.age = 40; // Silently fails (or throws in strict mode)
console.log(person.age); // 30

// Creating objects without prototype
const pureData = Object.create(null);
pureData.key = 'value';
console.log(pureData.toString); // undefined (no inherited methods)

// Prototype chain
const grandparent = { level: 'grandparent' };
const parent = Object.create(grandparent);
parent.level = 'parent';
const child = Object.create(parent);

console.log(child.level); // 'parent' (inherited)
delete parent.level;
console.log(child.level); // 'grandparent' (from grandparent)

Object.getPrototypeOf()

Returns the prototype of an object.

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

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

// Custom objects
function Person(name) {
  this.name = name;
}

const john = new Person('John');
console.log(Object.getPrototypeOf(john) === Person.prototype); // true

// Object.create
const base = { type: 'base' };
const derived = Object.create(base);
console.log(Object.getPrototypeOf(derived) === base); // true

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

Object.setPrototypeOf()

Sets the prototype of an object (use with caution for performance).

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

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

// Set prototype
Object.setPrototypeOf(dog, animal);
dog.speak(); // 'Animal sound'
dog.bark(); // 'Woof!'

// Changing prototype chain
const bird = {
  fly() {
    console.log('Flying');
  },
};

Object.setPrototypeOf(dog, bird);
// dog.speak(); // TypeError: dog.speak is not a function
dog.fly(); // 'Flying'

// Performance warning: Changing prototype is slow
// Better to use Object.create() when possible
const betterDog = Object.create(animal);
betterDog.bark = function () {
  console.log('Woof!');
};

Object Property Control

Methods for controlling object mutability and property characteristics.

Object.freeze()

Freezes an object: prevents new properties, removes existing properties, and prevents changing property values.

const obj = {
  name: 'John',
  age: 30,
};

Object.freeze(obj);

// Cannot add properties
obj.email = 'john@example.com';
console.log(obj.email); // undefined

// Cannot modify properties
obj.name = 'Jane';
console.log(obj.name); // 'John'

// Cannot delete properties
delete obj.age;
console.log(obj.age); // 30

// Check if frozen
console.log(Object.isFrozen(obj)); // true

// Shallow freeze only
const nested = {
  user: {
    name: 'John',
    settings: {
      theme: 'dark',
    },
  },
};

Object.freeze(nested);
nested.user.name = 'Jane'; // This works!
console.log(nested.user.name); // 'Jane'

// Deep freeze function
function deepFreeze(obj) {
  Object.freeze(obj);

  Object.values(obj).forEach((value) => {
    if (typeof value === 'object' && value !== null) {
      deepFreeze(value);
    }
  });

  return obj;
}

const deepFrozen = deepFreeze({
  user: {
    name: 'John',
    settings: {
      theme: 'dark',
    },
  },
});

deepFrozen.user.settings.theme = 'light'; // Silently fails
console.log(deepFrozen.user.settings.theme); // 'dark'

Object.seal()

Seals an object: prevents new properties and marking existing properties as non-configurable, but allows changing values.

const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
};

Object.seal(config);

// Cannot add properties
config.retry = 3;
console.log(config.retry); // undefined

// Can modify existing properties
config.timeout = 10000;
console.log(config.timeout); // 10000

// Cannot delete properties
delete config.apiUrl;
console.log(config.apiUrl); // 'https://api.example.com'

// Cannot reconfigure properties
// Object.defineProperty(config, 'timeout', { enumerable: false }); // TypeError

// Check if sealed
console.log(Object.isSealed(config)); // true

// Comparison with freeze
const frozen = Object.freeze({ value: 1 });
const sealed = Object.seal({ value: 1 });

frozen.value = 2; // Fails
sealed.value = 2; // Works

console.log(frozen.value); // 1
console.log(sealed.value); // 2

Object.preventExtensions()

Prevents new properties from being added to an object.

const user = {
  name: 'John',
};

Object.preventExtensions(user);

// Cannot add new properties
user.email = 'john@example.com';
console.log(user.email); // undefined

// Can modify existing properties
user.name = 'Jane';
console.log(user.name); // 'Jane'

// Can delete properties
delete user.name;
console.log(user.name); // undefined

// Check if extensible
console.log(Object.isExtensible(user)); // false

// Comparison of restrictions
const normal = {};
const nonExtensible = Object.preventExtensions({});
const sealed = Object.seal({});
const frozen = Object.freeze({});

console.log(Object.isExtensible(normal)); // true
console.log(Object.isExtensible(nonExtensible)); // false
console.log(Object.isExtensible(sealed)); // false
console.log(Object.isExtensible(frozen)); // false

Object Property Descriptors

Methods for working with property descriptors.

Object.getOwnPropertyDescriptor()

Returns a property descriptor for an own property.

const obj = {
  name: 'John',
};

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

// Custom descriptors
const custom = {};
Object.defineProperty(custom, 'readonly', {
  value: 42,
  writable: false,
  enumerable: true,
  configurable: false,
});

const customDesc = Object.getOwnPropertyDescriptor(custom, 'readonly');
console.log(customDesc);
// {
//   value: 42,
//   writable: false,
//   enumerable: true,
//   configurable: false
// }

// Getters and setters
const temperature = {
  _celsius: 0,
  get fahrenheit() {
    return (this._celsius * 9) / 5 + 32;
  },
  set fahrenheit(value) {
    this._celsius = ((value - 32) * 5) / 9;
  },
};

const getterDesc = Object.getOwnPropertyDescriptor(temperature, 'fahrenheit');
console.log(getterDesc);
// {
//   get: [Function: get fahrenheit],
//   set: [Function: set fahrenheit],
//   enumerable: true,
//   configurable: true
// }

Object.getOwnPropertyDescriptors()

Returns all own property descriptors of an object.

const obj = {
  name: 'John',
  age: 30,
};

Object.defineProperty(obj, 'id', {
  value: 123,
  writable: false,
});

const descriptors = Object.getOwnPropertyDescriptors(obj);
console.log(descriptors);
// {
//   name: { value: 'John', writable: true, enumerable: true, configurable: true },
//   age: { value: 30, writable: true, enumerable: true, configurable: true },
//   id: { value: 123, writable: false, enumerable: false, configurable: false }
// }

// Cloning with descriptors (including getters/setters)
const original = {
  _value: 42,
  get value() {
    return this._value;
  },
  set value(v) {
    this._value = v;
  },
};

// Simple spread doesn't copy getters/setters
const wrongClone = { ...original };
console.log(wrongClone.value); // 42 (but it's a regular property)

// Correct cloning
const correctClone = Object.create(
  Object.getPrototypeOf(original),
  Object.getOwnPropertyDescriptors(original)
);

correctClone.value = 100;
console.log(correctClone._value); // 100 (setter worked)

Object.defineProperty()

Defines a new property or modifies an existing property.

const person = {};

// Define a simple property
Object.defineProperty(person, 'name', {
  value: 'John',
  writable: true,
  enumerable: true,
  configurable: true,
});

// Define a read-only property
Object.defineProperty(person, 'id', {
  value: 12345,
  writable: false,
  enumerable: true,
  configurable: false,
});

// Define a computed property
Object.defineProperty(person, 'info', {
  get() {
    return `${this.name} (ID: ${this.id})`;
  },
  enumerable: true,
  configurable: true,
});

console.log(person.info); // 'John (ID: 12345)'

// Define property with validation
let _age;
Object.defineProperty(person, 'age', {
  get() {
    return _age;
  },
  set(value) {
    if (value < 0 || value > 150) {
      throw new Error('Invalid age');
    }
    _age = value;
  },
  enumerable: true,
  configurable: true,
});

person.age = 30; // OK
// person.age = 200; // Error: Invalid age

Object.defineProperties()

Defines multiple properties at once.

const product = {};

Object.defineProperties(product, {
  name: {
    value: 'Laptop',
    writable: true,
    enumerable: true,
  },
  price: {
    value: 999,
    writable: true,
    enumerable: true,
  },
  _stock: {
    value: 10,
    writable: true,
    enumerable: false,
  },
  inStock: {
    get() {
      return this._stock > 0;
    },
    enumerable: true,
  },
  addStock: {
    value: function (quantity) {
      this._stock += quantity;
    },
    writable: false,
    enumerable: false,
  },
});

console.log(product.name); // 'Laptop'
console.log(product.inStock); // true
product.addStock(5);
console.log(product._stock); // 15

// Creating objects with specific descriptors
function createImmutablePoint(x, y) {
  return Object.defineProperties(
    {},
    {
      x: { value: x, enumerable: true },
      y: { value: y, enumerable: true },
      toString: {
        value: function () {
          return `(${this.x}, ${this.y})`;
        },
        enumerable: false,
      },
    }
  );
}

const point = createImmutablePoint(10, 20);
point.x = 30; // Silently fails
console.log(point.toString()); // '(10, 20)'

Object Comparison and Copying

Object.is()

Determines whether two values are the same value.

// Similar to === but with some differences
console.log(Object.is(1, 1)); // true
console.log(Object.is('hello', 'hello')); // true
console.log(Object.is({}, {})); // false (different objects)

// Differences from ===
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true

console.log(0 === -0); // true
console.log(Object.is(0, -0)); // false

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

// Practical use cases
function indexOf(arr, searchElement) {
  for (let i = 0; i < arr.length; i++) {
    if (Object.is(arr[i], searchElement)) {
      return i;
    }
  }
  return -1;
}

const values = [1, NaN, 0, -0, 'test'];
console.log(indexOf(values, NaN)); // 1 (works with NaN)
console.log(indexOf(values, -0)); // 3 (distinguishes -0)

// In objects
const obj1 = { value: NaN };
const obj2 = { value: NaN };
console.log(obj1.value === obj2.value); // false
console.log(Object.is(obj1.value, obj2.value)); // true

Object.assign()

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

// Basic usage
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };

const result = Object.assign(target, source1, source2);
console.log(target); // { a: 1, b: 2, c: 3 }
console.log(result === target); // true (modifies target)

// Cloning objects (shallow)
const original = { a: 1, b: { c: 2 } };
const clone = Object.assign({}, original);

clone.a = 10;
clone.b.c = 20;
console.log(original.a); // 1 (primitive copied)
console.log(original.b.c); // 20 (object referenced)

// Merging objects
const defaults = {
  host: 'localhost',
  port: 8080,
  protocol: 'http',
};

const userConfig = {
  host: 'example.com',
  port: 443,
};

const config = Object.assign({}, defaults, userConfig);
console.log(config);
// { host: 'example.com', port: 443, protocol: 'http' }

// Property overwriting
const obj = { a: 1, b: 2 };
Object.assign(obj, { b: 3, c: 4 }, { b: 5 });
console.log(obj); // { a: 1, b: 5, c: 4 }

// Only copies enumerable properties
const source = Object.defineProperties(
  {},
  {
    enumerable: {
      value: 'yes',
      enumerable: true,
    },
    nonEnumerable: {
      value: 'no',
      enumerable: false,
    },
  }
);

const copied = Object.assign({}, source);
console.log(copied); // { enumerable: 'yes' }

// Type conversion
const v1 = 'abc';
const v2 = true;
const v3 = 10;

const obj2 = Object.assign({}, v1, v2, v3);
console.log(obj2); // { '0': 'a', '1': 'b', '2': 'c' }
// Only strings create enumerable properties

Object Transformation

Object.fromEntries()

Creates an object from an array of key-value pairs.

// Basic usage
const entries = [
  ['name', 'John'],
  ['age', 30],
  ['city', 'New York'],
];
const obj = Object.fromEntries(entries);
console.log(obj); // { name: 'John', age: 30, city: 'New York' }

// From Map
const map = new Map([
  ['a', 1],
  ['b', 2],
  ['c', 3],
]);
const objFromMap = Object.fromEntries(map);
console.log(objFromMap); // { a: 1, b: 2, c: 3 }

// Transforming objects
const prices = {
  apple: 1.5,
  banana: 0.8,
  orange: 2.0,
};

const discounted = Object.fromEntries(
  Object.entries(prices).map(([fruit, price]) => [fruit, price * 0.9])
);
console.log(discounted);
// { apple: 1.35, banana: 0.72, orange: 1.8 }

// Filtering and transforming
const data = {
  name: 'John',
  age: 30,
  _internal: 'hidden',
  email: 'john@example.com',
  _id: 123,
};

const publicData = Object.fromEntries(
  Object.entries(data)
    .filter(([key]) => !key.startsWith('_'))
    .map(([key, value]) => [key.toUpperCase(), value])
);
console.log(publicData);
// { NAME: 'John', AGE: 30, EMAIL: 'john@example.com' }

// Working with URLSearchParams
const params = new URLSearchParams('name=John&age=30&city=NYC');
const queryObj = Object.fromEntries(params);
console.log(queryObj); // { name: 'John', age: '30', city: 'NYC' }

Practical Examples and Patterns

Object Utility Functions

// Deep merge objects
function deepMerge(target, ...sources) {
  if (!sources.length) return target;

  for (const source of sources) {
    for (const key in source) {
      if (source.hasOwnProperty(key)) {
        if (
          typeof source[key] === 'object' &&
          source[key] !== null &&
          !Array.isArray(source[key])
        ) {
          target[key] = deepMerge(target[key] || {}, source[key]);
        } else {
          target[key] = source[key];
        }
      }
    }
  }

  return target;
}

// Pick specific properties
function pick(obj, keys) {
  return Object.fromEntries(
    Object.entries(obj).filter(([key]) => keys.includes(key))
  );
}

// Omit specific properties
function omit(obj, keys) {
  return Object.fromEntries(
    Object.entries(obj).filter(([key]) => !keys.includes(key))
  );
}

// Map object values
function mapValues(obj, fn) {
  return Object.fromEntries(
    Object.entries(obj).map(([key, value]) => [key, fn(value, key)])
  );
}

// Example usage
const user = {
  id: 1,
  name: 'John',
  email: 'john@example.com',
  password: 'secret',
  age: 30,
};

console.log(pick(user, ['name', 'email']));
// { name: 'John', email: 'john@example.com' }

console.log(omit(user, ['password']));
// { id: 1, name: 'John', email: 'john@example.com', age: 30 }

console.log(mapValues({ a: 1, b: 2, c: 3 }, (x) => x * 2));
// { a: 2, b: 4, c: 6 }

Working with Nested Objects

// Get nested property safely
function getNestedProperty(obj, path) {
  return path.split('.').reduce((current, key) => current?.[key], obj);
}

// Set nested property
function setNestedProperty(obj, path, value) {
  const keys = path.split('.');
  const lastKey = keys.pop();

  const target = keys.reduce((current, key) => {
    if (!(key in current) || typeof current[key] !== 'object') {
      current[key] = {};
    }
    return current[key];
  }, obj);

  target[lastKey] = value;
  return obj;
}

// Flatten nested object
function flattenObject(obj, prefix = '') {
  return Object.entries(obj).reduce((acc, [key, value]) => {
    const newKey = prefix ? `${prefix}.${key}` : key;

    if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
      Object.assign(acc, flattenObject(value, newKey));
    } else {
      acc[newKey] = value;
    }

    return acc;
  }, {});
}

// Example usage
const nested = {
  user: {
    name: 'John',
    address: {
      street: '123 Main St',
      city: 'NYC',
    },
  },
};

console.log(getNestedProperty(nested, 'user.address.city')); // 'NYC'

setNestedProperty(nested, 'user.phone.mobile', '555-1234');
console.log(nested.user.phone.mobile); // '555-1234'

console.log(flattenObject(nested));
// {
//   'user.name': 'John',
//   'user.address.street': '123 Main St',
//   'user.address.city': 'NYC',
//   'user.phone.mobile': '555-1234'
// }

Best Practices

  1. Choose the right method for the task
// Use Object.keys() for property names
Object.keys(obj).forEach((key) => {
  /* ... */
});

// Use Object.values() when you only need values
const sum = Object.values(scores).reduce((a, b) => a + b, 0);

// Use Object.entries() when you need both
Object.entries(obj).forEach(([key, value]) => {
  /* ... */
});
  1. Be aware of shallow vs deep operations
// Object.assign() is shallow
const shallow = Object.assign({}, deepObject);

// For deep cloning, use other methods
const deep = JSON.parse(JSON.stringify(deepObject));
// Or use a library like Lodash
  1. Consider performance implications
// Object.freeze() can improve performance for static data
const CONSTANTS = Object.freeze({
  API_URL: 'https://api.example.com',
  TIMEOUT: 5000,
});

// But avoid changing prototypes in hot code paths
// Object.setPrototypeOf() is slow
  1. Use descriptors for advanced property control
// Create truly private properties
const privateData = new WeakMap();

class User {
  constructor(name) {
    privateData.set(this, { name });

    Object.defineProperty(this, 'name', {
      get() {
        return privateData.get(this).name;
      },
      enumerable: true,
      configurable: false,
    });
  }
}

Conclusion

JavaScript's Object methods provide powerful tools for working with objects at every level - from simple property enumeration to complex property descriptor manipulation. Understanding these methods enables you to write more efficient, maintainable, and robust code. Whether you're transforming data, implementing security features, or creating complex object hierarchies, these methods form the foundation of advanced JavaScript object manipulation.