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 the in operator, you can use the hasOwnProperty 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.