I have this object function constructor:
const Shape = function(name){ this.name = name; } Shape.prototype.getName = function(){ return this.name; };
and I have this instance
const square = new Shape("square");
When I use for loop to iterate over the square object I can see that the iteration process is being happen over the prototype of the square object
for (const key in square) console.log(key); /* #output: name getName */
but when I use the Object.keys() function I can see that the iteration process is not iterating over the prototype object
/* #output: ["name"] */
What is the behind the scenes reason for that?
Here is what I’ve tried:
I’ve tried to console.log the descriptor of the getName method from the prototype object, I’ve seen that the enumerable attribute is set to true by default:
console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(square), "getName")) /* #output: configurable: true enumerable: true value: ƒ () writable: true __proto__: Object */
Advertisement
Answer
Object.keys
only iterates over enumerable own properties. In contrast, for..in
iterates over all enumerable properties anywhere on the object’s prototype chain.
With this code:
const Shape = function(name){ this.name = name; } Shape.prototype.getName = function(){ return this.name; };
A Shape
instance is receiving an own property of a name
, so it gets iterated over by both iteration methods. In contrast, getName
is on an instance’s prototype – it’s not a property of the instance itself, so it isn’t returned in Object.keys
:
const Shape = function(name){ this.name = name; } Shape.prototype.getName = function(){ return this.name; }; const square = new Shape("square"); console.log( square.hasOwnProperty('name'), square.hasOwnProperty('getName'), Shape.prototype.hasOwnProperty('getName') );