In such cases you can use an iterator explicitly.
Sometimes, you might want to use an iterator explicitly. You can do that, too, although it's a lot clunkier than for-of. It looks like this:
const a = ["a", "b", "c"];
const it = a.values();
let entry;
while (!(entry = it.next()).done) {
console.log(entry.value);
}
An iterator is an object matching the Iterator definition in the specification. Its next method returns a new result object each time you call it. The result object has a property, done, telling us whether it's done, and a property value with the value for that iteration. (done is optional if it would be false, value is optional if it would be undefined.)
The meaning of value varies depending on the iterator; arrays support (at least) three functions that return iterators:
values(): This is the one I used above. It returns an iterator where each value is the array entry for that iteration ("a", "b", and "c" in the example earlier).
keys(): Returns an iterator where each value is the key for that iteration (so for our a above, that would be "0", then "1", then "2").
entries(): Returns an iterator where each value is an array in the form [key, value] for that iteration