Home > Enterprise >  Why do inherited properties print later than other properties?
Why do inherited properties print later than other properties?

Time:10-19

let animal = {
  eats: true
};

let rabbit = {
  __proto__: animal, // (*)
  jumps: true, // (**)
};

console.log(Object.keys(rabbit)); // [jumps]

for(let prop in rabbit) console.log(prop); // jumps, eats

Why do inherited properties in the (*) line print later than property in the (**) line when we print properties in the for..in loop, even though the (*) line is above the (**) line?

CodePudding user response:

From the for...in article on MDN:

The loop will iterate over all enumerable properties of the object itself and those the object inherits from its prototype chain (properties of nearer prototypes take precedence over those of prototypes further away from the object in its prototype chain).

The traversal order, as of modern ECMAScript specification, is well-defined and consistent across implementations. Within each component of the prototype chain, all non-negative integer keys (those that can be array indices) will be traversed first in ascending order by value, then other string keys in ascending chronological order of property creation.

So, if you had included other properties on the prototype animal, and on rabbit, then those would be grouped by prototype, then ordered accordingly:

let animal = {
  isAnimal: true,
  eats: true,
};

let rabbit = {
  __proto__: animal,
  jumps: true,
  isRabbit: true,
};

console.log(Object.keys(rabbit)); // ["jumps", "isRabbit"]

for (let prop in rabbit) console.log(prop);
// jumps    (from rabbit)
// isRabbit (from rabbit)
// isAnimal (from animal)
// eats     (from animal)

CodePudding user response:

The for...in loop will capture inherited keys, whereas Object.keys will only access own properties.

The Object.* methods can only access direct properties of the object. If you want to avoid printing inherited properties, you will need an Object.prototype.hasOwnProperty check.

const animal = { eats: true };

const rabbit = {
  __proto__: animal, // (*)
  jumps: true, // (**)
};

console.log(Object.keys(rabbit)); // [jumps]

for (let prop in rabbit) {
  if (rabbit.hasOwnProperty(prop)) {
    console.log(prop); // jumps, but not eats
  }
}

for (let [prop] of Object.entries(rabbit)) {
  console.log(prop); // jumps
}

CodePudding user response:

Object.keys(obj) simply return an array of the object's own properties, whereas for...in additionally returns the keys found in the prototype chain.

Check the reference from MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

  • Related