Feathers Typeerror: Cannot Read Property 'symbol(Symbol.iterator) Fo Undefined
JavaScript supports a protocol by which objects such every bit arrays can exist used by command structures such as for…of and the spread operator ...
to loop through data sequentially. This is referred to as the iterable and the information structures that support this functionality are called iterables. While JavaScript provides maps, arrays and sets with an iterable belongings from the first, obviously objects do not have this past default.
Iterables are data structures which provide a mechanism to permit other data consumers to publicly access its elements in a sequential manner. Imagine a self-packaged data construction that unloads data one-by-one in lodge when put within of a for...of
loop.
The concept of the iterable protocol tin can be split into the iterable (the data construction itself) and the iterator (sort of a arrow that moves over the iterable). Permit's consider an assortment for case, when the assortment is used in a for...of
loop, the iterable holding is called which returns an iterator
. This iterable property is namespaced as Symbol.iterator
and the object that information technology returns can be used on a mutual interface that is shared by all looping control structures.
In a way, the Symbol.iterator
tin be compared to a iterator factory that produces an iterator whenever the data structure is placed in a loop.
As an iterator moves over the data structure and provides the elements sequentially, the object returned past the iterable contains a value
and a washed
property.
The value indicates the current data value pointed past the iterator and done
is a boolean that tells us if the iterator has reached the last element in the data structure.
This {value, done}
is consumed by structures such as loops. So how does the iterator method call the adjacent object? Using a next()
method that's defined within the Symbol.iterator() method.
A better definition for the iterator holding that I tin come with at this point is that information technology's an property that knows how to admission elements from a collection one past one and too provides a logical rule to terminate doing so (eg. if at that place are no more elements in the assortment).
Objects and Iterables
JavaScript objects are absurd and all, but why don't they accept iterables? Well, some of the reasons could be:
- Ane of the central features of objects is that it'due south user defined. Then slipping in a silent
[Symbol.iterator]()
into the object would make for a nasty surprise. - The to a higher place bespeak also means that it tin be added manually by the user, considering that all object compositions might not be similar. So having a mutual iterable property is pretty meaningless.
- If you want to loop over the meridian level elements in the object, then use the other guy: a
for...in
loop. - The usage of the Maps object type might be more appropriate.
All the points above except the last i (I hate to admit that I'm too comfy with regular objects to motility to maps) are good reasons not to accept iterables in objects, but what if your boss wanted your JavaScript objects to have i?
A simple iterable implementation on objects would look similar this:
permit Reptiles = { biomes : { h2o : [ "Alligators" , "Crocs" ] , state : [ "Snakes" , "Turtles" ] } , [Symbol.iterator] ( ) { allow reptilesByBiome = Object. values ( this .biomes) ; let reptileIndex = 0 ; let biomeIndex = 0 ; render { next ( ) { if (reptileIndex >= reptilesByBiome[biomeIndex] .length) { biomeIndex++ ; reptileIndex = 0 ; } if (biomeIndex >= reptilesByBiome.length) { return { value : undefined , washed : true } ; } return { value : reptilesByBiome[biomeIndex] [reptileIndex++ ] , done : false } ; } } ; } } ; // let's now iterate over our new `Reptiles` iterable: for ( let reptile of Reptiles) panel. log (reptile) ;
The output would exist:
Alligators Crocs Snakes Turtles
With this example, we see iterators tin can be implemented within the object. Iterables can exist powerful properties for objects that provide ease of apply while handling certain situations and aid us avert writing long path names.
Getting at the Iterator
Loops like for...of
have a built-in machinery to eat iterables until the washed
value evaluates to true. What if you want to swallow the iterable on your own though, without a born loop? Simple, you get the iterator from the iterable and then call adjacent() on it manually.
Given the same example as above, we could go an iterator from Reptiles
past calling its Symbol.iterator
like this:
permit reptileIterator = Reptiles[Symbol.iterator] ( ) ;
Y'all can then use the iterator like this:
console. log (reptileIterator. adjacent ( ) ) ; // {value: "Alligators", done: false} console. log (reptileIterator. next ( ) ) ; // {value: "Crocs", done: fake} console. log (reptileIterator. next ( ) ) ; // {value: "Snakes", done: false} console. log (reptileIterator. adjacent ( ) ) ; // {value: "Turtles", done: false} panel. log (reptileIterator. next ( ) ) ; // {value: undefined, washed: true} console. log (reptileIterator. next ( ) ) ; // TypeError: Cannot read property 'length' of undefined
As you tin can run into, the iterator has a next()
method that returns the side by side value in the iterable. The value for washed
only evaluates to truthful
after another next()
call once the concluding value has been returned, so to go over the entire iterable at that place will always exist one more than call to adjacent()
than there is data in the iterable. Calling next()
again later on an iterator has reached the stop of the itarable will result in a TypeError
existence thrown.
Wrapping Up
I hope that this introduction was eye opening in understanding a little more than about JavaScript'due south internals for data structures such as objects. This only scratched the surface and, if you want to learn more, I invite you to read Kyle Simpson's excellent affiliate on Iterables.
robinsonlinto1947.blogspot.com
Source: https://www.digitalocean.com/community/tutorials/js-iterables
Post a Comment for "Feathers Typeerror: Cannot Read Property 'symbol(Symbol.iterator) Fo Undefined"