If I created an array, for instance, var array=[1,2,3,4];
to return an iterator I would do var iterator = array[Symbol.iterator]();
I don't understand why you access the Symbol.iterator property through brackets? Why isn't it just array.Symbol.iterator
?
There is no property on an array called Symbol
(unless you put one there). Instead you are looking up the values whose key is the symbol primitive that Symbol.iterator
points to. Symbol.iterator
returns a symbol and you use that symbol as the lookup key. It's a little like looking up a property with a variable:
let a = [1, 2, 3]
a.someProp = "hello"
let key = "someProp"
// this doesn't work for the same reason s.Symbol.iterator doesn't:
// a.key
// but this does:
console.log(a[key])
// So with a Symbol:
let k = Symbol.iterator
console.log(typeof k)
// k is now a reference to the symbol that is the key
// you can use that to returns the iterator function
console.log(a[k]) // <-- that returns your iterator function
console.log([...a[k]()])
// equivalent to:
console.log([...a[Symbol.iterator]()])
Because that's how the iterable protocol works. See MDN:
The iterable protocol allows JavaScript objects to define or customize their iteration behavior, such as what values are looped over in a for..of construct. Some built-in types are built-in iterables with a default iteration behavior, such as Array or Map, while other types (such as Object) are not.
In order to be iterable, an object must implement the @@iterator method, meaning that the object (or one of the objects up its prototype chain) must have a property with a @@iterator key which is available via constant Symbol.iterator:
The interpreter needs a way to determine whether a generic object is iterable. While it could have been specified that each iterable object has a string iterator
property that, when called, returns an iterator for that object, that might be a problem for (pre-iterator) objects that may have happened to have the iterator
property but don't conform to the actual specification iterator protocol.
Requiring that the iterator property is accessed via a (unique, iterator-specific) Symbol
ensures that no such problematic collisions can take place.
(as a side note: array.Symbol.iterator
would require Symbol
to be a property of array
, which wouldn't make much sense - Symbol
is a global object)
array.Symbol.iterator
says "access the Symbol
member of the array
variable, and then access that value's iterator
member" however that will return the error Uncaught TypeError: Cannot read property 'iterator' of undefined
because the array doesn't have a member called Symbol
and so it returns undefined
and undefined
doesn't have an iterator
member.
The dot .
operator in JS is left-associative so it's evaluated from left-to-right. You need to use brackets to clarify what you want, and what you want is to access the iterator
of Symbol
and then use that value to access a member of the array
variable.
To use a math analogy, the difference between array.Symbol.iterator
and array[Symbol.iterator]
is like the difference between 6 / 0 + 2
(undefined, can't divide by 0) and 6 / (0 + 2)
(= 3, valid operation!).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With