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')
);