2022 Answer
If you are asking "Is foo
iterable" then you probably come from a language (PHP, Python) where that question has a single answer. In modern Javascript, there are different types of iterable. Therefore, you have to check the ability to iterate depending on what you want to do with the variable.
TL;DR
- Test the ability to iterate using
forEach()
with !!foo.forEach
, returns true on an Array.
- Test the ability to iterate using
for..of
with !!foo[Symbol.iterator]
, returns true on an Array or String.
- Test the ability to iterate using
for..in
with !!Object.keys(Object(foo)).length
, returns true on an Array, String, or Object.
Long answer
Let's define some variables:
const someNumber = 42;
42
const someArray = [1,2,3];
(3) [1, 2, 3]
const someString = "Hello";
"Hello, world!"
const someObject = {a:"A", b:"B"};
{a: "A", b: "B"}
Testing iterability with forEach()
Which types can be iterated with forEach()
, tested with !!foo.forEach
:
someNumber.forEach(x=>console.log(x));
VM1526:1 Uncaught TypeError: someNumber.forEach is not a function at <anonymous>:1:12
someArray.forEach(x=>console.log(x));
VM916:1 1
VM916:1 2
VM916:1 3
undefined
someString.forEach(x=>console.log(x));
VM957:1 Uncaught TypeError: someString.forEach is not a function at <anonymous>:1:12
someObject.forEach(x=>console.log(x));
VM994:1 Uncaught TypeError: someObject.forEach is not a function at <anonymous>:1:12
Only the Array seems to be iterable with forEach()
.
Testing iterability with for..of
Which types can be iterated with for..of
, tested with !!foo[Symbol.iterator]
:
for (x of someNumber) { console.log(x); }
VM21027:1 Uncaught TypeError: someNumber is not iterable at <anonymous>:1:11
for (x of someArray) { console.log(x); }
VM21047:1 1
VM21047:1 2
VM21047:1 3
undefined
for (x of someString) { console.log(x); }
VM21065:1 H
VM21065:1 e
VM21065:1 l
VM21065:1 l
VM21065:1 o
undefined
for (x of someObject) { console.log(x); }
VM21085:1 Uncaught TypeError: someObject is not iterable at <anonymous>:1:11
The Array and String seem to be iterable with for..of, but the Object is not. And both the Number and the Object threw an error.
Testing iterability with for..in
Which types can be iterated with for..in
, tested with !!Object.keys(Object(foo)).length
:
for (x in someNumber) { console.log(x); }
undefined
for (x in someArray) { console.log(x); }
VM20918:1 0
VM20918:1 1
VM20918:1 2
undefined
for (x in someString) { console.log(x); }
VM20945:1 0
VM20945:1 1
VM20945:1 2
VM20945:1 3
VM20945:1 4
undefined
for (x in someObject) { console.log(x); }
VM20972:1 a
VM20972:1 b
undefined
The Array, String, and Object all seem to be iterable with for..in
. And though it did not iterate, the Number did not throw an error.
In modern, ES6 Javascript I see forEach
used far more often than for..in
or for..of
. But Javascript developers must be aware of the differences between the three approaches, and the different behaviour of each approach.