CuteMachine

The Difference Between Object.keys And Object.getOwnPropertyNames In JavaScript

If you have programmed with JavaScript for a while, you will have seen the Object.keys() method calls and also the Object.getOwnPropertyNames() calls.

But what is the difference?

The Object.keys() Method

The Object.keys() method takes an object as an argument and returns all own enumerable properties of the passed object.

const obj = {
  foo: 1,
  bar: 2,
  baz: 3
}

Object.keys(obj)    // [ 'foo', 'bar', 'baz' ]

Because an array is also an object, we can pass an array to Object.keys() like so:

const arr = [1, 2, 3]
Object.keys(arr)    // [ '0', '1', '2' ]

The result is pretty much what one would expect.

The Object.getOwnPropertyNames() Method

The Object.getOwnPropertyNames() method returns all enumerable and non-enumerable property names in an array.

const obj = {
  foo: 1,
  bar: 2,
  baz: 3
}

Object.getOwnPropertyNames(obj)    // [ 'foo', 'bar', 'baz' ]

So the result for this example returns the same array of property names as the example for Object.keys().

Let's look at what happens when we call Object.getOwnPropertyNames() with an array.

const arr = [1, 2, 3]
Object.getOwnPropertyNames(arr)    // [ '0', '1', '2', 'length' ]

OK, now we see a difference in the result. The property name length is included in the results array.

We know that every array has a length property that holds the length of the collection. But when we iterate over the array, we certainly do not want to iterate over the length attribute. Therefore the property length is marked as non-enumerable.

Object.getOwnPropertyNames vs Object.keys

We have seen that both methods give us an object's own properties. The difference is that the keys() method only returns the own enumerable attributes, and the getOwnPropertyNames() method gives us all own properties.

You can test if an own property is enumerable with the propertyIsEnumerable() method.

const arr = [1, 2, 3]
Object.getOwnPropertyNames(arr)    // [ '0', '1', '2', 'length' ]
arr.propertyIsEnumerable('1')      // true
arr.propertyIsEnumerable('length') // false

Defining Enumerable And Non-enumerable Properties

To dig a little deeper into the difference, we can create an object and add two properties to it with Object.defineProperties(). Let's add the two properties foo and bar to an object, foo will be enumerable, and bar will be non-enumerable.

const obj = { }
Object.defineProperties(obj, { foo: { enumerable: true, value: 'enumerable foo'}})
Object.defineProperties(obj, { bar: { enumerable: false, value: 'non-enumerable bar'}})

Object.keys(obj)    // [ 'foo' ]
Object.getOwnPropertyNames(obj)    // [ 'foo', 'bar' ]

Posted on CuteMachine.

Jo's Profile ImageWritten by Jo who lives and works in Frankfurt building digital doodah. Stalk him on Twitter.

TOS • Privacy • Disclaimer