# JS Tip of the Day: Object.keys vs Array.keys

**URL:** <https://forum.kirupa.com/t/js-tip-of-the-day-object-keys-vs-array-keys/643508>\
**Category:** web dev\
**Created:** [July 8, 2020, 3:14pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-object-keys-vs-array-keys/643508 "2020-07-08T15:14:30Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![senocular](https://yyz1.discourse-cdn.com/flex011/user_avatar/forum.kirupa.com/senocular/32/7217_2.png) [@senocular](https://forum.kirupa.com/u/senocular)\
**Post date:** [July 8, 2020, 3:14pm UTC](https://forum.kirupa.com/t/js-tip-of-the-day-object-keys-vs-array-keys/643508/1 "2020-07-08T15:14:30Z")

</div>

**Object.keys vs Array.keys**  
Version: ES2015  
Level: Intermediate

Object has a static method, `Object.keys()`, which will return all of the enumerable, non-inherited keys of any object as an array. This can be used to easily iterate over all of the property names of an object.

```javascript
let petTypeByName = {
    Tweety: 'bird',
    Sylvester: 'cat',
    Hector: 'dog'
};

let names = Object.keys(petTypeByName);
console.log(names); // ['Tweety', 'Sylvester', 'Hector']

for (let name of names) {
    console.log(name);
}
/* logs:
Tweety
Sylvester
Hector
*/

```

Related methods include `Object.values()` and `Object.entries()` for getting an object’s values or key-value pairs respectively.

```javascript
for (let type of Object.values(petTypeByName)) {
    console.log(type);
}
/* logs:
bird
cat
dog
*/

for (let pair of Object.entries(petTypeByName)) {
    console.log(pair);
}
/* logs:
['Tweety', 'bird']
['Sylvester', 'cat']
['Hector', 'dog']
*/

```

Arrays (as well as Maps and Sets) also have their own `keys()` method which is accessible from their instances. This can similarly be used to iterate through the keys of an array.

```javascript
let names = ['Tweety', 'Sylvester', 'Hector'];
for (let index of names.keys()) {
    console.log(index);
}
/* logs:
0
1
2
*/

```

However, there is an important difference between `Object.keys()` and an array’s `keys()` method. While `Object.keys()` returns an array, `keys()` for array instances returns an iterator.

```javascript
let names = ['Tweety', 'Sylvester', 'Hector'];
console.log(Object.keys(names)); // ['0', '1', '2']
console.log(names.keys()); // Array Iterator {}

```

The same applies to the `values()` and `entries()` methods. The instance method versions of these functions (for arrays as well as Map and Set instances) return iterators instead of arrays.

```javascript
let names = ['Tweety', 'Sylvester', 'Hector'];
console.log(names.keys()); // Array Iterator {}
console.log(names.values()); // Array Iterator {}
console.log(names.entries()); // Array Iterator {}

```

In the case of arrays, these instance methods also account for all possible values from 0 up to the array length, which for sparse arrays, can account for array elements that don’t actually exist. The static methods on `Object` will only identify existing values.

```javascript
let names = [];
names[2] = 'Hector';

for (let index of names.keys()) {
    console.log(index);
}
/* logs:
0
1
2
*/

for (let index of Object.keys(names)) {
    console.log(index);
}
/* logs:
2
*/

```

You may notice that if you iterate through an array directly using a `for...of` loop, you’ll see that it will also account for all possible values from 0 up to the length. In fact, the implementation of the iterator used in for…of loops for arrays is the same implementation as the array `values()` method.

```javascript
let names = [];
names[2] = 'Hector';

for (let name of names) {
    console.log(name);
}
/* logs:
undefined
undefined
Hector
*/

console.log(names[Symbol.iterator] === names.values); // true

```

If you wanted an array of values matching those produced by the array `keys()` (or similar) method, you’d have to spread it into an array to get it since iterator objects are not themselves arrays or even array-like.

```javascript
let names = [];
names[2] = 'Hector';

console.log([...names.keys()]); // [undefined, undefined, 'Hector']

```

While there is no built-in way to get an iterator for object properties, there is a [proposal (stage 1) for improved object iteration](https://github.com/tc39/proposal-object-iteration) that would add the following static methods to `Object`, each providing an iterator rather than an array:

- `Object.iterateKeys()`
- `Object.iterateValues()`
- `Object.iterateEntries()`

These could provide benefit from not having to create an intermediary array for iteration through object properties.

More info:

- [Object.keys on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys)
- [Array keys on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/keys)

* * *

More tips: [JavaScript Tips of the Day](http://forum.kirupa.com/t/javascript-tip-of-the-day/641803/1)
