Demystifying Object.keys() and JavaScript's Prototype Chain

Demystifying Object.keys() and JavaScript's Prototype Chain

First, we will examine look into for...in vs Object.keys(). In JavaScript, both the for...in loop and Object.keys() method is used to work with the properties of objects. However, they differ in how they access and iterate over those properties. Let’s break down the differences and explore when to use each.

for...in Loop

The for...in loop is used to iterate over the enumerable properties of an object, including both own and inherited properties.

  • Iterates over enumerable properties (both own and inherited) of the object.

  • Can include properties from the prototype chain.

  • Useful when we want to include all enumerable keys, including inherited ones.

Example:

let obj = { name: "Hridoy", age: 20, city: "Dhaka" };

for (let key in obj) {
    console.log(key); // Outputs: name, age, city
}

Object.keys()

The Object.keys() method returns an array of the object's own enumerable properties, excluding inherited properties from the prototype chain.

  • Only includes the properties directly defined on the object itself.

  • Returns an array of property names.

Example:

let obj = { name: "Hridoy", age: 20, city: "Dhaka" };

console.log(Object.keys(obj)); // Outputs: [ 'name', 'age', 'city' ]

Key Differences

Here’s a quick comparison of how for...in and Object.keys() behave:

Featurefor...inObject.keys()
Includes prototype propertiesYesNo
Returns inherited propertiesYesNo
Output typeIterates directly (no array)Returns an array
Best use caseTraversing all enumerable properties, including inherited onesListing only the object's own properties

When They Differ

What happens if we add a property to the prototype chain of an object?

Object.prototype.country = "Bangladesh"; // Adding an inherited property

let obj = { name: "Hridoy", age: 20, city: "Dhaka" };

for (let key in obj) {
    console.log(key); // Outputs: name, age, city, country
}

console.log(Object.keys(obj)); // Outputs: [ 'name', 'age', 'city' ]
  • The for...in loop includes the inherited property country (from Object.prototype).

  • Object.keys() excludes it, returning only the properties directly defined on obj.

Best Practice

  • Use for...in when you want to loop through all enumerable properties, including inherited ones.

  • Use Object.keys() when you want to retrieve only the object's own properties.

In cases where inheritance doesn’t matter, Object.keys() is usually preferred for clarity and to avoid unexpected inherited properties.