Why does Object.keys () and Object.getOwnPropertyNames () produce different output when calling a Proxy object with its ownKeys handler?

I have the following proxy:

const p = new Proxy({}, { ownKeys(target) { return ['a', 'b']; }, }); 

MDN says that:

This trap can intercept these operations:

  • Object.getOwnPropertyNames()
  • Object.getOwnPropertySymbols()
  • Object.keys()
  • Reflect.ownKeys()

Therefore, I expected Object.getOwnPropertyNames() and Object.keys() the same result. However, Object.getOwnPropertyNames(p) returns ['a', 'b'] (as expected), but Object.keys(p) returns an empty array. Why is this?

In addition, if I add a property to this object that is not returned by the ownKeys handler (for example, c ), it is ignored by both functions (they do not change their output). However, when I add a property that is returned by the ownKeys handler (for example, a ), Object.keys(p) now returns ['a'] .

Code snippet:

 const p = new Proxy({}, { ownKeys(target) { return ['a', 'b']; }, }); console.log(Object.getOwnPropertyNames(p)); // ['a', 'b'] console.log(Object.keys(p)); // [] pc = true; console.log(Object.getOwnPropertyNames(p)); // ['a', 'b'] console.log(Object.keys(p)); // [] pa = true; console.log(Object.getOwnPropertyNames(p)); // ['a', 'b'] console.log(Object.keys(p)); // ['a'] 
+7
javascript ecmascript-6 es6-proxy
source share
2 answers

The difference between Object.keys() and Object.getOwnPropertyNames() is that Object.keys() will call [[GetOwnProperty]] for the object and only add the property to the list of results if the return property descriptor is listed, since the object is not has such a property, [[GetOwnProperty]] will return undefined and the (name) property will be ignored.

You can overwrite / implement [[GetOwnProperty]] in the proxy by running getOwnPropertyDescriptor :

 const p = new Proxy({}, { ownKeys(target) { return ['a', 'b']; }, getOwnPropertyDescriptor(k) { return { enumerable: true, configurable: true, }; } }); console.log(Object.getOwnPropertyNames(p)); // ['a', 'b'] console.log(Object.keys(p)); // ['a', 'b'] 
+8
source share

The difference between Object.keys and Object.getOwnPropertyNames is that the latter returns its own properties, regardless of whether they are enumerable or not.

Properties added to the Proxy object are not enumerable and will not be displayed in Object.keys , but will be in Object.getOwnPropertyNames

Typically, properties added by a property assignment or initializer are enumerated by default, and properties added by methods such as Object.assign , new Proxy , etc. are not enumerated by default.

Here is more information about ownership and enumerability on MDN , where you can also find this table that describes the difference in the two methods.

enter image description here

+9
source share

All Articles