{"id":696,"date":"2025-12-11T13:43:31","date_gmt":"2025-12-11T13:43:31","guid":{"rendered":"http:\/\/guupon.com\/index.php\/2025\/12\/11\/javascript-for-everyone-iterators-2\/"},"modified":"2025-12-11T13:43:31","modified_gmt":"2025-12-11T13:43:31","slug":"javascript-for-everyone-iterators-2","status":"publish","type":"post","link":"http:\/\/guupon.com\/index.php\/2025\/12\/11\/javascript-for-everyone-iterators-2\/","title":{"rendered":"JavaScript For Everyone: Iterators"},"content":{"rendered":"<p><html> <head> <meta charset=\"utf-8\"> <link rel=\"canonical\" href=\"https:\/\/www.smashingmagazine.com\/2025\/10\/javascript-for-everyone-iterators\/\" \/> <title>JavaScript For Everyone: Iterators<\/title> <\/head> <body> <\/p>\n<article>\n<header>\n<h1>JavaScript For Everyone: Iterators<\/h1>\n<address>Mat Marquis<\/address>\n<p> <time datetime=\"2025-10-27T13:00:00&#43;00:00\" class=\"op-published\">2025-10-27T13:00:00+00:00<\/time> <time datetime=\"2025-10-27T13:00:00&#43;00:00\" class=\"op-modified\">2025-12-11T13:32:54+00:00<\/time> <\/header>\n<p>Hey, I\u2019m Mat, but \u201cWilto\u201d works too &mdash; I\u2019m here to teach you JavaScript. Well, not <em>here<\/em>-here; technically, I\u2019m over at <a href=\"https:\/\/piccalil.li\/javascript-for-everyone\">Piccalil.li\u2019s <em>JavaScript for Everyone<\/em><\/a> course to teach you JavaScript. The following is an excerpt from the <strong>Iterables and Iterators<\/strong> module: the lesson on Iterators.<\/p>\n<p>Iterators are one of JavaScript\u2019s more linguistically confusing topics, sailing <em>easily<\/em> over what is already a pretty high bar. There are <em>iterables<\/em> &mdash; array, Set, Map, and string &mdash; all of which follow the <strong>iterable protocol<\/strong>. To follow said protocol, an object must implement the <strong>iterable interface<\/strong>. In practice, that means that the object needs to include a <code>[Symbol.iterator]()<\/code> method somewhere in its prototype chain. Iterable protocol is one of two <strong>iteration protocols<\/strong>. The other iteration protocol is the <strong>iterator protocol<\/strong>.<\/p>\n<p>See what I mean about this being linguistically fraught? Iterables implement the iterable iteration interface, and iterators implement the iterator iteration interface! If you can say that five times fast, then you\u2019ve pretty much got the gist of it; easy-peasy, right?<\/p>\n<p>No, listen, by the time you reach the end of this lesson, I promise it won\u2019t be half as confusing as it might sound, especially with the context you\u2019ll have from the lessons that precede it.<\/p>\n<p>An <strong>iterable<\/strong> object follows the iterable protocol, which just means that the object has a conventional method for making iterators. The elements that it contains can be looped over with <code>for<\/code>\u2026<code>of<\/code>.<\/p>\n<p>An <strong>iterator<\/strong> object follows the iterator protocol, and the elements it contains can be accessed <em>sequentially<\/em>, one at a time.<\/p>\n<div data-audience=\"non-subscriber\" data-remove=\"true\" class=\"feature-panel-container\">\n<aside class=\"feature-panel\" style=\"\">\n<div class=\"feature-panel-left-col\">\n<div class=\"feature-panel-description\">\n<p>Meet <strong><a data-instant href=\"\/printed-books\/image-optimization\/\">Image Optimization<\/a><\/strong>, Addy Osmani\u2019s new practical guide to optimizing and delivering <strong>high-quality images<\/strong> on the web. Everything in one single <strong>528-pages<\/strong> book.<\/p>\n<p> <a data-instant href=\"https:\/\/www.smashingmagazine.com\/printed-books\/image-optimization\/\" class=\"btn btn--green btn--large\" style=\"\">Jump to table of contents&nbsp;\u21ac<\/a><\/div>\n<\/p><\/div>\n<div class=\"feature-panel-right-col\"><a data-instant href=\"https:\/\/www.smashingmagazine.com\/printed-books\/image-optimization\/\" class=\"feature-panel-image-link\"> <\/p>\n<div class=\"feature-panel-image\"><picture><source type=\"image\/avif\" srcSet=\"https:\/\/archive.smashing.media\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/2c669cf1-c6ef-4c87-9901-018b04f7871f\/image-optimization-shop-cover-opt.avif\" \/><img loading=\"lazy\" decoding=\"async\" class=\"feature-panel-image-img\" src=\"https:\/\/archive.smashing.media\/assets\/344dbf88-fdf9-42bb-adb4-46f01eedd629\/87fd0cfa-692e-459c-b2f3-15209a1f6aa7\/image-optimization-shop-cover-opt.png\" alt=\"Feature Panel\" width=\"480\" height=\"697\" \/> <\/picture> <\/div>\n<p> <\/a> <\/div>\n<\/aside><\/div>\n<p>To <em>reiterate<\/em> &mdash; a play on words for which I do not forgive myself, nor expect you to forgive me &mdash; an <strong>iterator<\/strong> object follows iterator protocol, and the elements it contains can be accessed <em>sequentially<\/em>, one at a time. Iterator protocol defines a standard way to produce a sequence of values, and optionally <code>return<\/code> a value once all possible values have been generated.<\/p>\n<p>In order to follow the iterator protocol, an object has to &mdash; you guessed it &mdash; implement the <strong>iterator interface<\/strong>. In practice, that once again means that a certain method has to be available somewhere on the object&rsquo;s prototype chain. In this case, it\u2019s the <code>next()<\/code> method that advances through the elements it contains, one at a time, and returns an object each time that method is called.<\/p>\n<p>In order to meet the iterator interface criteria, the returned object must contain two properties with specific keys: one with the key <code>value<\/code>, representing the value of the current element, and one with the key <code>done<\/code>, a Boolean value that tells us if the iterator has advanced beyond the final element in the data structure. That\u2019s not an awkward phrasing the editorial team let slip through: the value of that <code>done<\/code> property is <code>true<\/code> only when a call to <code>next()<\/code> results in an attempt to access an element <em>beyond<\/em> the final element in the iterator, not upon accessing the final element in the iterator. Again, a lot in print, but it\u2019ll make more sense when you see it in action.<\/p>\n<p>You\u2019ve seen an example of a built-in iterator before, albeit briefly:<\/p>\n<pre><code class=\"language-jsx\">const theMap = new Map([ [ \"aKey\", \"A value.\" ] ]); console.log( theMap.keys() ); \/\/ Result: Map Iterator { constructor: Iterator() } <\/code><\/pre>\n<p>That\u2019s right: while a Map object itself is an iterable, Map\u2019s built-in methods <code>keys()<\/code>, <code>values()<\/code>, and <code>entries()<\/code> all return Iterator objects. You\u2019ll also remember that I looped through those using <code>forEach<\/code> (a relatively recent addition to the language). Used that way, an iterator is indistinguishable from an iterable:<\/p>\n<pre><code class=\"language-jsx\">const theMap = new Map([ [ \"key\", \"value \" ] ]); theMap.keys().forEach( thing =&gt; { console.log( thing ); }); \/\/ Result: key <\/code><\/pre>\n<p>All iterators are iterable; they all implement the iterable interface:<\/p>\n<pre><code class=\"language-jsx\">const theMap = new Map([ [ \"key\", \"value \" ] ]); theMap.keys()[ Symbol.iterator ]; \/\/ Result: function Symbol.iterator() <\/code><\/pre>\n<p>And if you\u2019re angry about the increasing blurriness of the line between iterators and iterables, wait until you get a load of this \u201ctop ten anime betrayals\u201d video candidate: I\u2019m going to demonstrate how to interact with an iterator by using an array.<\/p>\n<p>\u201cBOO,\u201d you surely cry, having been so betrayed by one of your oldest and most indexed friends. \u201cArray is an itera<em>ble<\/em>, not an itera<em>tor<\/em>!\u201d You are both right to yell at me in general, and right about array in specific &mdash; an array <em>is<\/em> an iterable, not an iterator. In fact, while all iterators are iterable, none of the built-in iterables are iterators.<\/p>\n<p>However, when you call that <code>[ Symbol.iterator ]()<\/code> method &mdash; the one that defines an object as an iterable &mdash; it returns an iterator object created from an iterable data structure:<\/p>\n<pre><code class=\"language-jsx\">const theIterable = [ true, false ]; const theIterator = theIterable[ Symbol.iterator ](); theIterable; \/\/ Result: Array [ true, false ] theIterator; \/\/ Result: Array Iterator { constructor: Iterator() } <\/code><\/pre>\n<p>The same goes for Set, Map, and &mdash; yes &mdash; even strings:<\/p>\n<pre><code class=\"language-jsx\">const theIterable = \"A string.\" const theIterator = theIterable[ Symbol.iterator ](); theIterator; \/\/ Result: String Iterator { constructor: Iterator() } <\/code><\/pre>\n<p>What we\u2019re doing here manually &mdash; creating an iterator from an iterable using <code>%Symbol.iterator%<\/code> &mdash; is precisely how iterable objects work internally, and why they have to implement <code>%Symbol.iterator%<\/code> in order to <em>be<\/em> iterables. Any time you loop through an array, you\u2019re actually looping through an iterator created from that Array. All built-in iterators <em>are<\/em> iterable. All built-in iterables can be used to <em>create<\/em> iterators.<\/p>\n<p>Alternately &mdash; <em>preferably<\/em>, even, since it doesn\u2019t require you to graze up against <code>%Symbol.iterator%<\/code> directly &mdash; you can use the built-in <code>Iterator.from()<\/code> method to create an iterator object from any iterable:<\/p>\n<pre><code class=\"language-jsx\">const theIterator = Iterator.from([ true, false ]); theIterator; \/\/ Result: Array Iterator { constructor: Iterator() } <\/code><\/pre>\n<p>You remember how I mentioned that an iterator has to provide a <code>next()<\/code> method (that returns a very specific Object)? Calling that <code>next()<\/code> method steps through the elements that the iterator contains one at a time, with each call returning an instance of that Object:<\/p>\n<pre><code class=\"language-jsx\">const theIterator = Iterator.from([ 1, 2, 3 ]); theIterator.next(); \/\/ Result: Object { value: 1, done: false } theIterator.next(); \/\/ Result: Object { value: 2, done: false } theIterator.next(); \/\/ Result: Object { value: 3, done: false } theIterator.next(); \/\/ Result: Object { value: undefined, done: true } <\/code><\/pre>\n<p>You can think of this as a more controlled form of traversal than the traditional \u201cwind it up and watch it go\u201d <code>for<\/code> loops you\u2019re probably used to &mdash; a method of accessing elements one step at a time, as-needed. Granted, you don\u2019t <em>have<\/em> to step through an iterator in this way, since they have their very own <code>Iterator.forEach<\/code> method, which works exactly like you would expect &mdash; to a point:<\/p>\n<pre><code class=\"language-jsx\">const theIterator = Iterator.from([ true, false ]); theIterator.forEach( element =&gt; console.log( element ) ); \/&#42; Result: true false &#42;\/ <\/code><\/pre>\n<p>But there\u2019s another big difference between iterables and iterators that we haven\u2019t touched on yet, and for my money, it actually goes a long way toward making <em>linguistic<\/em> sense of the two. You might need to humor me for a little bit here, though.<\/p>\n<p>See, an iterable object is an object that is iterable. No, listen, stay with me: you can iterate over an Array, and when you\u2019re done doing so, you can still iterate over that Array. It is, by definition, an object that can be iterated over; it is the essential nature of an iterable to be iterable:<\/p>\n<pre><code class=\"language-jsx\">const theIterable = [ 1, 2 ]; theIterable.forEach( el =&gt; { console.log( el ); }); \/&#42; Result: 1 2 &#42;\/ theIterable.forEach( el =&gt; { console.log( el ); }); \/&#42; Result: 1 2 &#42;\/ <\/code><\/pre>\n<p>In a way, an iterator object represents the singular <em>act<\/em> of iteration. Internal to an iterable, it is the mechanism by which the iterable is iterated over, each time that iteration is performed. As a stand-alone iterator object &mdash; whether you step through it using the <code>next<\/code> method or loop over its elements using <code>forEach<\/code> &mdash; once iterated over, that iterator is <em>past tense<\/em>; it is <em>iterated<\/em>. Because they maintain an internal state, the essential nature of an iterator is to be iterated over, singular:<\/p>\n<pre><code class=\"language-jsx\">const theIterator = Iterator.from([ 1, 2 ]); theIterator.next(); \/\/ Result: Object { value: 1, done: false } theIterator.next(); \/\/ Result: Object { value: 2, done: false } theIterator.next(); \/\/ Result: Object { value: undefined, done: true } theIterator.forEach( el =&gt; console.log( el ) ); \/\/ Result: undefined <\/code><\/pre>\n<p>That makes for neat work when you&rsquo;re using the Iterator constructor\u2019s built-in methods to, say, filter or extract part of an Iterator object:<\/p>\n<div class=\"break-out\">\n<pre><code class=\"language-jsx\">const theIterator = Iterator.from([ \"First\", \"Second\", \"Third\" ]); \/\/ Take the first two values from `theIterator`: theIterator.take( 2 ).forEach( el =&gt; { console.log( el ); }); \/&#42; Result: \"First\" \"Second\" &#42;\/ \/\/ theIterator now only contains anything left over after the above operation is complete: theIterator.next(); \/\/ Result: Object { value: \"Third\", done: false } <\/code><\/pre>\n<\/p><\/div>\n<p>Once you reach the end of an iterator, the act of iterating over it is complete. Iterated. Past-tense.<\/p>\n<p>And so too is your time in this lesson, you might be relieved to hear. I know this was kind of a rough one, but the good news is: this course is iterable, not an iterator. This step in your iteration through it &mdash; this lesson &mdash; may be over, but the essential nature of this course is that you can iterate through it again. Don\u2019t worry about committing all of this to memory right now &mdash; you can come back and revisit this lesson anytime.<\/p>\n<div class=\"partners__lead-place\"><\/div>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>I stand by what I wrote there, unsurprising as that probably is: this lesson is a tricky one, but listen, <em>you got this<\/em>. <a href=\"https:\/\/piccalil.li\/javascript-for-everyone\">JavaScript for Everyone<\/a> is designed to take you inside JavaScript\u2019s head. Once you\u2019ve started seeing how the gears mesh &mdash; seen the fingerprints left behind by the people who built the language, and the good, bad, and sometimes baffling decisions that went into that &mdash; no <em>itera-<\/em>, whether <em>-ble<\/em> or <em>-tor<\/em> will be able to stand in your way.<\/p>\n<figure class=\" break-out article__image \"> <a href=\"https:\/\/piccalil.li\/javascript-for-everyone\"> <img loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" width=\"800\" height=\"450\" srcset=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/javascript-for-everyone-iterators\/1-javascript-for-everyone.png 400w, https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_800\/https:\/\/files.smashing.media\/articles\/javascript-for-everyone-iterators\/1-javascript-for-everyone.png 800w, https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_1200\/https:\/\/files.smashing.media\/articles\/javascript-for-everyone-iterators\/1-javascript-for-everyone.png 1200w, https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_1600\/https:\/\/files.smashing.media\/articles\/javascript-for-everyone-iterators\/1-javascript-for-everyone.png 1600w, https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_2000\/https:\/\/files.smashing.media\/articles\/javascript-for-everyone-iterators\/1-javascript-for-everyone.png 2000w\" src=\"https:\/\/res.cloudinary.com\/indysigner\/image\/fetch\/f_auto,q_80\/w_400\/https:\/\/files.smashing.media\/articles\/javascript-for-everyone-iterators\/1-javascript-for-everyone.png\" sizes=\"auto, 100vw\" alt=\"Javascript for everyone course announcement\" \/> <\/a><figcaption class=\"op-vertical-bottom\"> <a href='https:\/\/piccalil.li\/javascript-for-everyone'>JavaScript for Everyone<\/a> is now available and the launch price runs until midnight, October 28. Save \u00a360 off the full price of \u00a3249 and get it for \u00a3189! (<a href='https:\/\/files.smashing.media\/articles\/javascript-for-everyone-iterators\/1-javascript-for-everyone.png'>Large preview<\/a>) <\/figcaption><\/figure>\n<p>My goal is to teach you the <em>deep magic<\/em> &mdash; the <em>how<\/em> and the <em>why<\/em> of JavaScript, using the syntaxes you\u2019re most likely to encounter in your day-to-day work, at your pace and on your terms. If you\u2019re new to the language, you\u2019ll walk away from this course with a foundational understanding of JavaScript worth hundreds of hours of trial-and-error. If you\u2019re a junior developer, you\u2019ll finish this course with a depth of knowledge to rival any senior.<\/p>\n<p>I hope to see you there.<\/p>\n<div class=\"signature\"> <img src=\"https:\/\/www.smashingmagazine.com\/images\/logo\/logo--red.png\" alt=\"Smashing Editorial\" width=\"35\" height=\"46\" loading=\"lazy\" decoding=\"async\" \/> <span>(gg, yk)<\/span> <\/div>\n<\/article>\n<p> <\/body> <\/html><\/p>\n","protected":false},"excerpt":{"rendered":"<p class=\"text-justify mb-2\" >Here is a lesson on Iterators: iterables implement the iterable iteration interface, and iterators implement the iterator iteration interface. Sounds confusing? Mat breaks it all down in the article.<\/p>\n","protected":false},"author":0,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-696","post","type-post","status-publish","format-standard","hentry","category-javascript"],"_links":{"self":[{"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/posts\/696","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/comments?post=696"}],"version-history":[{"count":0,"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/posts\/696\/revisions"}],"wp:attachment":[{"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/media?parent=696"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/categories?post=696"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/guupon.com\/index.php\/wp-json\/wp\/v2\/tags?post=696"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}