Does Object.keys(anObject) return anObject's prototype? [duplicate]
I'm reading Eloquent JavaScript's Map section and I'm having trouble understanding its last paragraph:
If you do have a plain object that you need to treat as a map for some reason, it is useful to know that
Object.keys
returns only an object’s own keys, not those in the prototype. As an alternative to thein
operator, you can use thehasOwnProperty
method, which ignores the object’s prototype.
I then assume that Object.keys
does not return the properties and methods an object gets from the inheritance of its prototype. So I tried the following:
var anObject = {};
console.log(Object.keys(anObject)); //Array []
console.log("toString" in Object.keys(anObject)); //true
console.log(anObject.hasOwnProperty("toString")); //false
Apparently, toString
is in the array returned by Object.keys(anObject)
, but an empty array is returned when I logged its keys? Did I understand the passage wrongly?
You understood the passage correctly, the usage of in
here is wrong though.
It returns true, since the Array that Object.keys(anObject)
returns has a property called toString
in it's prototype. in
also checks the prototype, while hasOwnProperty
only checks the properties an Object actually has (meaning the properties that were "manually added" to the empty Object).
But it doesn't have an "own property" with the name toString
let anObject = {};
let keys = Object.keys(anObject);
console.log("toString" in keys); //true, since there is a property "toString" in the keys.prototype object
console.log(keys.hasOwnProperty("toString")); //false, since there aren't any properties in the object itself
Object.keys(anObject)
returns an array, and toString
is a valid method on arrays.
Since in
checks for a property in the object, and in its prototype chain, the expression "toString" in Object.keys(anObject)
returns true
.
But this doesn't mean that toString
is an owned property of anObject
. That's why anObject.hasOwnProperty("toString")
returns false
.
The
in
operator returns true if the specified property is in the specified object or its prototype chain.
As we all know, arrays are special types of object in Javascript with methods/properties like forEach(), length, map(), toString(), sort() and more. These aforementioned methods are present in the prototype of the array and not in the array itself. Whereas, hasOwnProperty
only checks the properties the Object actually has and not in its prototype. Read more about the in
operator here. Also, use Object.prototype.hasOwnProperty.call(obj, prop)
instead of obj.hasOwnProperty(prop)
. Read Why? here.