<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Ben Mildren</title>
    <description>The latest articles on Forem by Ben Mildren (@mildrenben).</description>
    <link>https://forem.com/mildrenben</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F25042%2F7e83349c-f5b8-4bdb-bed0-f361ad61039b.jpg</url>
      <title>Forem: Ben Mildren</title>
      <link>https://forem.com/mildrenben</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mildrenben"/>
    <language>en</language>
    <item>
      <title>7 JavaScript blogs to follow going into 2021</title>
      <dc:creator>Ben Mildren</dc:creator>
      <pubDate>Thu, 10 Sep 2020 15:58:32 +0000</pubDate>
      <link>https://forem.com/mildrenben/javascript-blogs-to-follow-going-into-2021-29df</link>
      <guid>https://forem.com/mildrenben/javascript-blogs-to-follow-going-into-2021-29df</guid>
      <description>&lt;p&gt;This blog post is from &lt;a href="https://webdesignrepo.com"&gt;webdesignrepo&lt;/a&gt;'s list of best Blogs and News websites.&lt;/p&gt;

&lt;p&gt;Discover the best tools and links at &lt;a href="https://webdesignrepo.com"&gt;webdesignrepo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS-Tricks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FmJOR7w8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/unsi1w404ltp7ikh2jus.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FmJOR7w8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/unsi1w404ltp7ikh2jus.png" alt="CSS-Tricks homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite having CSS in the title, &lt;a href="https://css-tricks.com/"&gt;CSS-Tricks&lt;/a&gt; focuses on all aspects of Frontend development. &lt;br&gt;
You may know them from their world famous "&lt;a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/"&gt;A Complete Guide to Flexbox&lt;/a&gt;" article, you only have to google flexbox for this to be top. They show off lots of new JS features and post a bunch of tutorials on how to things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post frequency&lt;/strong&gt;: Multiple times a day&lt;br&gt;
&lt;strong&gt;Standout feature&lt;/strong&gt;: Variety of content&lt;/p&gt;

&lt;h2&gt;
  
  
  David Walsh
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P2vy5XBW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vy5j62juau182i7fw64y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P2vy5XBW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/vy5j62juau182i7fw64y.png" alt="David Walsh homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://davidwalsh.name/"&gt;David Walsh&lt;/a&gt; has been cranking out posts since 2007! He is a veteran in the field and knows JS like the back of his hand. David Walsh has some amazing API reference guides where he distills complex topics into easy to digest language, a prime example being "&lt;a href="https://davidwalsh.name/promises"&gt;JavaScript Promise API&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post frequency&lt;/strong&gt;: Several times a month&lt;br&gt;
&lt;strong&gt;Standout feature&lt;/strong&gt;: Solid fundamentals&lt;/p&gt;

&lt;h2&gt;
  
  
  Codrops
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DYun8t3L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dhushshls6j6hdl2smbr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DYun8t3L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dhushshls6j6hdl2smbr.gif" alt="Codrops demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Do you like fancy animations? You'll love &lt;a href="https://tympanus.net/codrops/category/tutorials/"&gt;Codrops&lt;/a&gt; then. They publish demos and tutorials for some weird and wonderful animations, often leaning heavily into canvas, WebGL, Three.js etc. Here's a &lt;a href="https://tympanus.net/Tutorials/WaveMotionEffect/"&gt;wave motion tutorial&lt;/a&gt; they posted from earlier this year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post frequency&lt;/strong&gt;: Once a month&lt;br&gt;
&lt;strong&gt;Standout feature&lt;/strong&gt;: Beautiful animations&lt;/p&gt;

&lt;h2&gt;
  
  
  Flavio Copes
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mw5qCrt0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dpvq61kf8556m1xen75d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mw5qCrt0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/dpvq61kf8556m1xen75d.png" alt="Flavio Copes homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://flaviocopes.com/"&gt;Flavio Copes&lt;/a&gt; has posted a blog every single day since January 2018. One man, one post, every single day. The commitment is outstanding! Either that or he lost a bet with the devil and is forced to post every day for all eternity. Devil's doing or not, it's a great blog for consumers and teaches lots of JS (and non-JS) stuff in really short bites. Some of it is beginner level, some intermediate, some advanced, so there's something for everyone. I would recommend Flavio for beginners as he explains core concepts well. If you use Google a lot, you're bound to run into Flavio's posts sooner or later, with titles like "&lt;a href="https://flaviocopes.com/javascript-check-empty-object/"&gt;How to test for an empty object in JavaScript&lt;/a&gt;" that explain small things well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post frequency&lt;/strong&gt;: Daily&lt;br&gt;
&lt;strong&gt;Standout feature&lt;/strong&gt;: Bite sized posts&lt;/p&gt;

&lt;h2&gt;
  
  
  Tania Rascia
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KOTP7qZl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u7fgrexbb47fpdmlhuge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KOTP7qZl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/u7fgrexbb47fpdmlhuge.png" alt="Tania Rascia homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If I could only recommend one blog it would probably be &lt;a href="https://www.taniarascia.com/blog"&gt;Tania Rascia's blog&lt;/a&gt;. It mostly covers a lot of fundamentals as well as some experimental stuff, but most importantly it's very measured. When you look at Tania's blog history, it feels like every post matters, with &lt;em&gt;almost&lt;/em&gt; every post being solid reading for all JS developers of all levels. It's just solid blog posts all the way down. Check out "&lt;a href="https://www.taniarascia.com/git-submodules-private-content/"&gt;Using Git submodules for private content&lt;/a&gt;" for a taste.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post frequency&lt;/strong&gt;: A couple times a month&lt;br&gt;
&lt;strong&gt;Standout feature&lt;/strong&gt;: Long form tutorials&lt;/p&gt;

&lt;h2&gt;
  
  
  Scotch
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AlQfPJ4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qk0zebm9mx6k6kfq32nb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AlQfPJ4G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/qk0zebm9mx6k6kfq32nb.png" alt="Scotch.io homepage"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm more of a whiskey man myself, but who can deny how good &lt;a href="https://scotch.io/"&gt;Scotch&lt;/a&gt; tutorials are for free? They've been in the game for a long time posting tutorials and courses for popular frameworks and JS apis like React, Authentication, APIs, Tailwind and more. If you like video courses or longer form tutorial posts, Scotch is for you. Their latest tutorial is "&lt;a href="https://scotch.io/tutorials/add-social-login-to-ionic-apps"&gt;Add social login to Ionic apps&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post frequency&lt;/strong&gt;: A couple times a month&lt;br&gt;
&lt;strong&gt;Standout feature&lt;/strong&gt;: Long form tutorials&lt;/p&gt;

&lt;h2&gt;
  
  
  Josh Comeau
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VYc-WpzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/twqw778b9x1ba7f9hfqo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VYc-WpzA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/twqw778b9x1ba7f9hfqo.png" alt="Josh Comeau"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a brief hiatus, &lt;a href="https://joshwcomeau.com/"&gt;Josh Comeau&lt;/a&gt; is back! Josh writes about a lot of different topics, and although unconfirmed, it feels to me like Josh writes about problems he stumbles into in real life, at least that's the vibe I get from reading. Rather than churning out content for SEO, Josh's blog feels like a diary of his recent programming hurdles and how he overcame them. You'll get a real array of content with Josh, dark mode, Netlify, Gatsby, speaking at conferences, but he used to work at Gatsby so he does blog a lot about React and Gatsby if that's your thing. Check his post "&lt;a href="https://joshwcomeau.com/react/animated-sparkles-in-react/"&gt;Animated sparkles in React&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Post frequency&lt;/strong&gt;: A couple times a month&lt;br&gt;
&lt;strong&gt;Standout feature&lt;/strong&gt;: His menu goes bloop&lt;/p&gt;




&lt;p&gt;Stay up to date with all Javascript and Frontend related resources at &lt;a href="https://webdesignrepo.com"&gt;webdesignrepo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>blog</category>
      <category>html</category>
      <category>css</category>
    </item>
    <item>
      <title>5 best tools for writing Javascript documentation</title>
      <dc:creator>Ben Mildren</dc:creator>
      <pubDate>Tue, 18 Aug 2020 21:22:35 +0000</pubDate>
      <link>https://forem.com/mildrenben/5-best-tools-for-writing-javascript-documentation-4m7i</link>
      <guid>https://forem.com/mildrenben/5-best-tools-for-writing-javascript-documentation-4m7i</guid>
      <description>&lt;p&gt;This blog post is from &lt;a href="https://webdesignrepo.com" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt;'s list of best documentation tools.&lt;/p&gt;

&lt;p&gt;Discover the best tools and links at &lt;a href="https://webdesignrepo.com" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Easiest setup
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8mtcpf57mziy5x2jaq59.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F8mtcpf57mziy5x2jaq59.png" alt="Docusaurus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docusaurus.io/en/" rel="noopener noreferrer"&gt;Docusaurus&lt;/a&gt; makes it easy to maintain documentation in a git repo. Your documentation files are just markdown files that live alongside your code, and the website is built for you automatically.&lt;/p&gt;

&lt;p&gt;Perfect for open source projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best documentation for components
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffzwl9o4bedtnd0r07d52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffzwl9o4bedtnd0r07d52.png" alt="Storybook dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://storybook.js.org/" rel="noopener noreferrer"&gt;Storybook&lt;/a&gt; is documentation for your components. React or vue or angular, they all work inside Storybook. It's a great way to showcase your components in a styleguide style way. You can also toggle state/props easily to show functionality of the components. &lt;/p&gt;

&lt;h2&gt;
  
  
  Most enterprise level
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnjmslfyjsdjal12yv3rl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnjmslfyjsdjal12yv3rl.png" alt="Wiki.js dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wiki.js.org/" rel="noopener noreferrer"&gt;Wiki.js&lt;/a&gt; is easily the most flexible documentation framework. It has enterprise level features like localization, 2FA authentication and user management so you're probably wondering what the pricing tier looks like, but it's actually free and open source. Overkill for smaller projects, however for larger or company wide documentation it's unrivaled. &lt;/p&gt;

&lt;h2&gt;
  
  
  Most stable
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuehrtfbuzive5n8l8c3c.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fuehrtfbuzive5n8l8c3c.jpeg" alt="JSDoc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Originally released in 2011, &lt;a href="https://github.com/jsdoc/jsdoc" rel="noopener noreferrer"&gt;JSDoc&lt;/a&gt; is certainly showing it's age now. But with age comes maturity, and this sure is one tried and tested documentation generator. It's stable and feature-full although a little dated visually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Best multi language support
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fri0ed1qe162lcnvrbri3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fri0ed1qe162lcnvrbri3.png" alt="Slate docs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/slatedocs/slate" rel="noopener noreferrer"&gt;Slate&lt;/a&gt; is very much inspired by Stripe's amazing documentation and they don't hide it. If you like Stripe's API docs, you'll love Slate with it's multi language support and clean look. &lt;/p&gt;

&lt;p&gt;Slate works best with API documentation.&lt;/p&gt;




&lt;p&gt;Hopefully you've found the javascript documentation generator to fit your needs!&lt;/p&gt;

&lt;p&gt;For more of the best dev resources be sure to check out &lt;a href="https://webdesignrepo.com" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>javascript</category>
      <category>tool</category>
      <category>api</category>
    </item>
    <item>
      <title>How I built webdesignrepo in 17 days with JAMstack</title>
      <dc:creator>Ben Mildren</dc:creator>
      <pubDate>Wed, 22 Jul 2020 08:04:00 +0000</pubDate>
      <link>https://forem.com/mildrenben/how-i-built-webdesignrepo-in-17-days-with-jamstack-2mfk</link>
      <guid>https://forem.com/mildrenben/how-i-built-webdesignrepo-in-17-days-with-jamstack-2mfk</guid>
      <description>&lt;p&gt;&lt;a href="https://webdesignrepo.com" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt; – New dev &amp;amp; design links every day. Plus a collection of helpful links.&lt;/p&gt;

&lt;p&gt;Here's how I built it in 17 days. (Whilst staying inside as many free tiers as possible)&lt;/p&gt;

&lt;h3&gt;
  
  
  Deciding the stack
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://webdesignrepo.com" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt; consists of two things: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A large repository of top notch links, to serve as a reference point for designers and developers, almost like a big list of bookmarks.&lt;/li&gt;
&lt;li&gt;A daily links section, where new interesting articles, research, projects, tidbits are posted. New additions to the repository get posted here also, with a little star showing they're special and they've been "saved" to the repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, all I needed was a system where I could add these links (and tags, icons etc) and the site would build each day. Seemed a no brainer to run JAMstack over a bulky database.&lt;/p&gt;

&lt;p&gt;The stack I settled on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gatsby (React based static site generator)&lt;/li&gt;
&lt;li&gt;Sanity (Amazing headless CMS)&lt;/li&gt;
&lt;li&gt;Netlify (Hosting and build pipeline)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's for the website, but I also used Azure Functions, Sendy (emails) and a raspberry pi, I'll get to those bits later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 1 - Setting up the project
&lt;/h3&gt;

&lt;p&gt;I created two github repositories, one for Gatsby the frontend and one for Sanity the CMS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.sanity.io/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; is so fast to set up a quick schema with, I added a basic "Daily link" document type and added a new document into my CMS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.gatsbyjs.org/" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt; is also quick to get up and running, although you do need to remove a fair few boilerplate files that aren't needed. &lt;/p&gt;

&lt;p&gt;I used the &lt;a href="https://www.gatsbyjs.org/packages/gatsby-source-sanity/" rel="noopener noreferrer"&gt;gatsby-source-sanity&lt;/a&gt; plugin to start pulling in data from the CMS at build time.&lt;/p&gt;

&lt;p&gt;Sanity and Gatsby have both written articles on how to use the combo together, you can see them here: &lt;a href="https://www.gatsbyjs.com/guides/sanity/" rel="noopener noreferrer"&gt;Gatsby's guide&lt;/a&gt; and &lt;a href="https://www.sanity.io/blog/get-started-with-gatsby-and-structured-content" rel="noopener noreferrer"&gt;Sanity's guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I was already pulling in data from the CMS! Here's what I had end of day 1:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6532a6k1xl3qsd8fxpg8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6532a6k1xl3qsd8fxpg8.png" alt="Day 1 progress"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 2 - Organizing by days
&lt;/h3&gt;

&lt;p&gt;Each day there are 3-5 daily links posted. I needed links to be ordered by day so that we could show "Monday – x, y, z" then "Tuesday - a, b, c" etc. So the schema for these daily links now looked as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;New link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;newLink&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;document&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Label&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;label&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;link&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Post date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postDate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Added to vault&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;addedToVault&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;addedToVault&lt;/code&gt; is whether the link was also added to the repo. Vault was a dumb word I used at the start and never bothered to change. I use the word vault interchangeably with repo links going forward. I regret this and should've changed to repo early.&lt;/p&gt;

&lt;p&gt;For those who haven't seen Sanity, here's what that schema translates to:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7tubinlhr7rwcxj4xm3f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F7tubinlhr7rwcxj4xm3f.png" alt="Sanity CMS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here's how it looked organized by day:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgt7ng64h8pvnxymv2i3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgt7ng64h8pvnxymv2i3h.png" alt="Day 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I continued to add a basic scaffold for what the repository of links might look like. Again, I set up a basic schema for these repository links and pulled the data into Gatsby.&lt;/p&gt;

&lt;p&gt;Sanity encourages you to split your data logically, rather than based on what appears near other things visually. It's interesting once you get into this mindset but it did take me a moment. &lt;/p&gt;

&lt;p&gt;For example, I have separate document types for Categories, Subcategories, and Vault Links. So you go to the CMS, add a new Category like Plugins. You then add a new Subcategory like Animation, which is linked to the Plugins parent category. You then add a vault link, which is linked to the Animation subcategory. It allows for any part of the chain to be renamed, replaced or changed without interfering with the rest.&lt;/p&gt;

&lt;p&gt;I added a few dummy vault links in and I began pulling the data into the frontend. I also added a search bar but it didn't do anything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsy0cp3yq432yhmhoxbdo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsy0cp3yq432yhmhoxbdo.png" alt="Day 2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Continuing into the evening, I cleaned up the design a little and moved it towards how I wanted it to look:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fugf3ge4mc1lama928i3q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fugf3ge4mc1lama928i3q.png" alt="Day 2"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Day 3 - CSS and removing future posts
&lt;/h3&gt;

&lt;p&gt;I added even more CSS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2pmwvhye5641no4an53w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F2pmwvhye5641no4an53w.png" alt="Day 3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When adding daily links, I might schedule them to be a day or two in the future. So I needed a way to remove these future posts and only show links from "today" and in the past. This seems like a very simple concept, but I actually ran into a few issues with Gatsby on this front.&lt;/p&gt;

&lt;p&gt;The issue comes from Gatsby only allowing static queries in components. So querying data based on the date was out of the window inside components. I needed my graphql query to look like this (with &lt;code&gt;SERVER_DATE&lt;/code&gt; being something like &lt;code&gt;2020-12-25&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;query&lt;/span&gt; &lt;span class="nx"&gt;loadNewLinksQuery&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;allSanityNewLink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;postDate&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nx"&gt;order&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DESC&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nl"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;postDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;lte&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;${SERVER_DATE}&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pages in Gatsby work slightly differently, and aren't static in the same way. But you can't use template literals in page queries either 😞 You &lt;em&gt;can&lt;/em&gt; pass through query variables via page context, but that felt a little pointless, so I ended up making basically all my API calls (to Sanity) in &lt;code&gt;gatsby-node.js&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Although annoying to not be calling the data inside components, I did end up doing a fair amount of logic inside &lt;code&gt;gatsby-node.js&lt;/code&gt; after calling the data and passing it to the  page components, so it did start to make more sense as I went along. That said, I'd love to see Gatsby allow template literal queries or query variables in components.&lt;/p&gt;

&lt;p&gt;I ordered all the links by date in &lt;code&gt;gatsby-node&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 4 - Animating days and archive pages
&lt;/h3&gt;

&lt;p&gt;With &lt;a href="https://www.framer.com/motion/" rel="noopener noreferrer"&gt;framer-motion&lt;/a&gt; (React animation library) imported, I set out to animate the transitions between days. This actually took a lot longer than expected, as is often the case with animation, it just takes a long time tweaking to make it feel perfect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpnror02b4xp69cm25mvf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpnror02b4xp69cm25mvf.gif" alt="Day 4 animation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Later in the day, I added archive pages. These are pretty straight forward. I wanted to show 7 days on the homepage that the user could flick through, then after 7 days it'd take them to an archive page which showed 10-20 "daily" links on one page, and the user could keep going back in time if they wanted to.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftnnena2gtu4gxvfh0vtm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ftnnena2gtu4gxvfh0vtm.png" alt="Day 4 archive pages"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 5 - Minor CSS
&lt;/h3&gt;

&lt;p&gt;Day 5 was a pretty slow day and I took a quick stab at how the styling might look for the repo section. This was a job I was putting off and didn't want to do, because organizing a huge amount of data like this to be scanable and readable is quite a difficult design challenge.&lt;/p&gt;

&lt;p&gt;Here's how it looked early on:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3sawbmjqd2u0nx9x7kqi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3sawbmjqd2u0nx9x7kqi.png" alt="Day 5"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 6 - Search page
&lt;/h3&gt;

&lt;p&gt;The search bar had sat at the top of the page for almost the entire time building this and had been totally useless. Today was it's day to shine!&lt;/p&gt;

&lt;p&gt;A search function was something I knew not many users would use, but would be of massive help to that fraction of users that did. So I built it.&lt;/p&gt;

&lt;p&gt;First off, I had to add tags to each link. I knew that just providing search through the labels/domains wouldn't be as helpful without the tags. So each repo link and each daily link now accept an array of references to tag documents (read: you can add a list of tags). In Sanity schema code it looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tags&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;array&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;reference&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tag&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;required&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff6bi10p6yzs1yehkw380.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff6bi10p6yzs1yehkw380.png" alt="Day 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each tag document only had one field: a label.&lt;/p&gt;

&lt;p&gt;So I created a bunch of tags that I knew would be used a lot: 'Javascript', 'React', 'CSS' and figured I'd add the rest as I needed them.&lt;/p&gt;

&lt;p&gt;With the tags set up, I went about creating what I can only describe as a &lt;strong&gt;very&lt;/strong&gt; rudimentary search function. &lt;code&gt;gatsby-node&lt;/code&gt; grabs &lt;em&gt;every&lt;/em&gt;. &lt;em&gt;single&lt;/em&gt;. &lt;em&gt;link&lt;/em&gt;. along with each links tags and passes them all to the &lt;code&gt;/search&lt;/code&gt; page. Then the search page checks the URL for params, and does a giant filter. &lt;/p&gt;

&lt;p&gt;So, user is on the homepage. Types "react animation" into the search input and hits enter. They get moved to &lt;code&gt;/search?terms=react,animation&lt;/code&gt;. The search page extracts those search terms, and then filters the giant list of links to the few that contain those terms in either the label, domain or tags of a link.&lt;/p&gt;

&lt;p&gt;This is not a great solution. I'm totally aware and as the site grows larger this solution will get worse and worse. So within the next couple months I'm going to rebuild it in some fashion, but hey, it works for now.&lt;/p&gt;

&lt;p&gt;As you can see below, I even added a "How search works" box to tell people just how crappy this search was.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg8j5gjvmugvrs021amjb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg8j5gjvmugvrs021amjb.png" alt="Day 6"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You might've also spotted a newsletter subscription box in the footer! I actually added that Day 5 and it shows up in a few places.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 7-11 - Replacing Mailchimp
&lt;/h3&gt;

&lt;p&gt;Ahh Mailchimp. Mailchimp is a great tool – but it is very expensive. In an effort to keep this rebuild as free as possible, I decided to ditch Mailchimp as my newsletter sender of choice. I had amassed 2000 email subscribers from webdesignrepo's following before, and needed a cheaper way to send them all update emails. Introducing &lt;a href="https://sendy.co/" rel="noopener noreferrer"&gt;Sendy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Sendy is a self hosted email solution. It's PHP based (which I'm not familiar with) and uses Amazon SES to send the emails. I went with Sendy as it's a one off cost of 59USD. That 59 bucks will pay itself back within a month or two and then I'll be sending emails basically for free.&lt;/p&gt;

&lt;p&gt;Hosting Sendy seems very easy, and it probably is if you're a regular person who fires up a DigitalOcean droplet to run it on or any other server. But I had a Raspberry Pi Zero W sat in my drawer that I'd never used and figured I'd put it to the task. If I have one regret in this whole thing, it's this part.&lt;/p&gt;

&lt;p&gt;I will spare all the details, but basically I ran into a &lt;em&gt;ton&lt;/em&gt; of issues. This is &lt;strong&gt;not&lt;/strong&gt; Sendy's fault, it was due to me running it on the Pi from my home network. I had never "connected a device to the internet" before, which is weird to say as a professional senior front end developer but it's just not something I'd done before. I've always used cloud servers.&lt;/p&gt;

&lt;p&gt;Suffice to say, I learnt a whole lot during this process about connecting devices to the internet. A few things I figured out after lots of googling:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You (kind of) need a static IP for your device. And domestic internet providers don't really offer that. Your home internet changes it's IP fairly often. So I set my Pi to be static &lt;em&gt;internally&lt;/em&gt;, so other devices on the same network could always find it under the same IP. But it also needs an external static IP so I could point foo.com to 123.111.222.333 and be sure that the IP wouldn't change. I needed to either upgrade to enterprise level internet for a static IP (not going to happen) or to find another solution. Turns out there is another way! Many domain providers (or DNS) offer dynamic DNS. I'm with namecheap and all I had to do was set up an A+ record for my subdomain and point it to my network IP. So A+ record for foo.webdesignrepo.com pointed at 123.111.222.333. Namecheap has a URL that you can hit to update the IP of that A+ record. So, I set up a cron job on my Pi to ping that namecheap URL every 5 minutes, and if my networks IP has changed namecheap will update the A+ record. Awesome!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now I have foo.webdesignrepo.com pointed to my networks IP. What happens next? Again, I felt embarrassed for not knowing this, but hey it was a great learning exercise. Once you have your domain pointed at your network IP, you need to forward those requests onto the right internal IP. So I setup port forwarding on my router to move :80 traffic onto my raspberry pi (which has a static internal IP). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I tested out the newsletter signup button locally and it worked! The new webdesignrepo was (secretly) hosted at v4.webdesignrepo.com, so I fired it up and tried to sign up to the newsletter and it failed. The signup box on the website just pings foo.webdesignrepo.com and says "Hey! &lt;a href="mailto:ben@mildren.com"&gt;ben@mildren.com&lt;/a&gt; wants to sign up". The problem stemmed from v4.webdesignrepo.com being served over HTTPS, and the Sendy installation being on HTTP (&lt;a href="http://foo.webdesignrepo.com" rel="noopener noreferrer"&gt;http://foo.webdesignrepo.com&lt;/a&gt;). So  the browser blocked the request. Or the Sendy server blocked the request. One of the two, honestly I can't remember what blocked what but I remember it not working. So I needed foo.webdesignrepo.com to be served over HTTPS. I had used Let's Encrypt before so figured this would be easy to get the SSL certificate. Turns out the Pi Zero W has issues with it due to limited RAM. Bummer. After jumping through a million hoops to get the Pi to use Lets Encrypt correctly...it still failed when trying to sign up. This was my lowest point 😂 Honestly I was so close to switching to Mailchimp, at this point I'd spent 3 or 4 days on this thing and all of that time was spent trawling through forum posts trying to fix issue after issue. After what felt like an eternity, I stumbled across the answer and it was simple. HTTPS' default port is 443 🤦‍♂️ So I setup the port forwarding for 443 and what do you know everything worked.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At this point, I had everything working with Sendy on my Pi Zero W! It honestly took me days and I hated most of it but I learnt so much from this.&lt;/p&gt;

&lt;p&gt;With the setup out of the way, I could start firing emails. So I started a new github repo called 'webdesignrepo-newsletter-sender' and this part was pretty straight forward. It's just a small node app that grabs today's links down from Sanity, then constructs some basic HTML for the email with those links in, and then it pings foo.webdesignrepo.com with the email HTML. Sendy then sends out the email. Easy.&lt;/p&gt;

&lt;p&gt;I set this on cron job to complete every day.&lt;/p&gt;

&lt;p&gt;So despite the tedious few days where I was close to crying, I had effectively set up a Mailchimp alternative for about 70USD total (Sendy is 59USD and the Pi was 9GBP I think).&lt;/p&gt;

&lt;p&gt;Sending 2000 emails a day, 30 days a month, with Amazon SES works out to be 6USD, not bad.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 12-13 - Accessibility and mobile designs
&lt;/h3&gt;

&lt;p&gt;I want webdesignrepo to be accessible to all, so I added all the relevant aria attributes where needed and started working on the focus order.&lt;/p&gt;

&lt;p&gt;I spent a while thinking about how the focus order should work and settled on this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://imgur.com/a/cLyYhq7" rel="noopener noreferrer"&gt;You can see the tab focus order here&lt;/a&gt; (for some reason dev.to won't let me embed this gif)&lt;/p&gt;

&lt;p&gt;I asked Twitter what the best way to handle focus order for these items would be and nobody replied.&lt;/p&gt;

&lt;p&gt;A11y is important to me and I want to be as inclusive as possible, so if something doesn't look right, work right, or screenreaders aren't working as expected at &lt;a href="https://webdesignrepo.com/" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt; then please ping me on &lt;a href="https://twitter.com/webdesignrepo" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and let me know.&lt;/p&gt;

&lt;p&gt;At this point the whole site was coming together but I had only been designing for desktop. So I got to work on the responsive side of things, constantly testing along the way to make sure everything felt right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1lsd529d82fmsq63xfe0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1lsd529d82fmsq63xfe0.png" alt="Day 12 mobile design progress"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 14 - Images for each post
&lt;/h3&gt;

&lt;p&gt;I wanted each daily link to have a little icon next to the link for the website, like a favicon/logo. Adding this &lt;em&gt;sounds&lt;/em&gt; trivial but in practice was a little more involved.&lt;/p&gt;

&lt;p&gt;Sanity has 500k limit per month on it's CDN for assets, which is actually super generous, but I wanted to stay within the free tier for as long as possible, and I might pass the 500k image requests sooner than you'd think. &lt;/p&gt;

&lt;p&gt;Some math:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There are 7 days displayed on the homepage of daily links&lt;/li&gt;
&lt;li&gt;Each of those days has 3-5 links, let's assume it's 5&lt;/li&gt;
&lt;li&gt;That's 5 * 7. 35 little logo images on the homepage alone&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With every pageview, I'd use 35 CDN requests. If a user wanted to go further back in time, each archive page hold 10 days worth of links which is 50 more images.&lt;/p&gt;

&lt;p&gt;Even assuming that nobody every visits an archive page (for 50 more requests), 500,000 / 35 is 14,285 pageviews.&lt;/p&gt;

&lt;p&gt;So at 14k pageviews a month, I'd have to start paying for CDN access. Granted, Sanity's costs are real cheap at 1USD per every extra 100k requests (which is around 3k pageviews). And Sanity does deserve my money, I think they've made an amazing product and I'm happy to pay for it, but I really was thinking of this as an exercise in scaling for as low cost as possible (just for the fun of it).&lt;/p&gt;

&lt;p&gt;As well as the costs, I'd have to upload a logo for every single link. Sure, some are re-used a lot, I post a lot of Github links, CSS-tricks etc. But I also post a ton of smaller blogs that I may only post once. I didn't want to upload an image for every single link.&lt;/p&gt;

&lt;p&gt;Alternatively, I could have a bot go and grab the images for me. Favicons are unfortunately too small, as I wanted at least 64x64px. Twitter images and Facebook open graph images worked decently enough though, higher res and often of the website logo! But for the same reason as above, I didn't want to do this for every image as it would cost a lot of money, probably way more than just using Sanity's CDN.&lt;/p&gt;

&lt;p&gt;I needed a balance of both. &lt;/p&gt;

&lt;p&gt;What I actually went with is three different ways of getting the images. Here's how it works:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I added Icon as a document type in Sanity, so I can upload images. I added a field onto the DailyLink schema to select these icons. For the most often used websites, I downloaded an image of their logo, resized to 64x64 and ran through TinyPNG, then uploaded to Sanity. In &lt;code&gt;gatsby-node&lt;/code&gt;, (which runs during the gatsby build process) when I request all the daily links, I also request the icons. This means the icons are only requested once a day. Each icon is then base64'd and placed directly inside the code. Lightning fast for users, keeps me inside the free tier and only adds ~20kb to the page load. This only works for the sites I post the most, I currently only have around 20 icons saved.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I built a serverless function and hosted it on Azure. I pass it a list of URLs and it returns a list of twitter and FB open graph images as URLs. Honestly, I could've used my Pi for this but it's slow at this kind of thing and I didn't want that to be a point of failure, my Pi has enough on it's plate. Azure's cloud functions also have a &lt;a href="https://azure.microsoft.com/en-us/pricing/details/functions/" rel="noopener noreferrer"&gt;generous free tier&lt;/a&gt;. You get 400,000 GB-s, that's gigabyte seconds. I'll spare the math, but with my function taking around a second to run each time, that works out at around 3 million function invocations. Again, in &lt;code&gt;gastby-node&lt;/code&gt; at build time, I call this cloud function with all the URLs on the homepage (excluding ones I already have images for from Sanity). I then add these image URLs into the code, and they're requested from the website in questions servers.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fidfast5eo8sl7xojsmrh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fidfast5eo8sl7xojsmrh.png" alt="Azure function pricing"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For archive pages, for when a user goes back in time, these images are not supplied. When a page loads and finds links without a base64 image (from Sanity) or a URL src (from the links site), it calls the Azure function with a list of URLs and then fetches those images.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a little convoluted, a three step process for something quite trivial, but it does work and it is free.&lt;/p&gt;

&lt;p&gt;To recap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I add popular images into the CMS. They're base64'd into the code&lt;/li&gt;
&lt;li&gt;Azure function is called for remaining missing images on homepage, twitter/open graph URLs used.&lt;/li&gt;
&lt;li&gt;For archive pages, nothing is embedded at build time and the Azure function is called by the client to fetch twitter/open graph images.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Was this worth it? 🤷‍♂️ It was fun to try to reduce costs as much as possible though&lt;/p&gt;

&lt;p&gt;The only issue with this system, is some of these smaller blogs I post are hosted on servers without HTTPS. So webdesignrepo makes HTTP calls to assets and some browsers note this in the security padlock icon. That's something I'll have to think about.&lt;/p&gt;

&lt;h3&gt;
  
  
  Day 15-16 - Adding all the data
&lt;/h3&gt;

&lt;p&gt;I tidied up the design for the repo section:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9nar668u36ny7aghk2zj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9nar668u36ny7aghk2zj.png" alt="Repo section"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I added a menu button for quickly navigating the repo:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F76ajq2cfpdoikndnicm0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F76ajq2cfpdoikndnicm0.png" alt="Navigation menu"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With the bulk of the site complete, I just had to add the data. I had hundreds of links in bookmarks for this, all organized by category and subcategory. I estimate adding them all to the CMS took 8-12 hours. Of course, it's taken me years to collect such a great set of links.&lt;/p&gt;

&lt;p&gt;Sanity does have an API for adding stuff which could've made this quicker, but once I got into a rhythm it wasn't so bad. It was actually quite therapeutic after such chaos with the Sendy Pi setup to have a mindless task like this.&lt;/p&gt;
&lt;h3&gt;
  
  
  Day 17 - Cron jobs and Twitter bot
&lt;/h3&gt;

&lt;p&gt;I have a Twitter account for webdesignrepo and wanted to post all new daily links there every day without having to do it myself.&lt;/p&gt;

&lt;p&gt;Using the &lt;a href="https://www.npmjs.com/package/twit" rel="noopener noreferrer"&gt;Twit&lt;/a&gt; library, it's so simple to set up this kind of bot. I spun up a new repo, created one index file and it was done. It requests today's links and posts them spread across the day. I also added a twitter handle field on the daily link Sanity schema, so I add that in when adding new links and the Twitter bot tweets like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;label&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;twitter_handle&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;link&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is simplified but at it's core that is all it does. The tags I add to each daily link (and repo link) for searchability are great for twitter which also uses hashtags. Again, cron job this bad boy and it's good to go.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fas84evjgvvon4579594u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fas84evjgvvon4579594u.png" alt="A tweet example"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Usually when you set up a headless CMS with a static site generator you'd have the site rebuild every time data is added to the CMS. I've done this before with Gatsby and Sanity, but it's actually not what I wanted or needed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://webdesignrepo.com/" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt; only needs to rebuild once a day at 6am to show the new daily links. Netlify offers a really simple webhook for this, and when you ping the URL it rebuilds so I set up a cron job on the Pi to rebuild the site every day.&lt;/p&gt;

&lt;h3&gt;
  
  
  That's all folks
&lt;/h3&gt;

&lt;p&gt;There were lots of smaller things not mentioned in this post like: adding the 'added to repo' icon, favicon/social media icons, meta/SEO stuff, adding sponsored tags, testing etc.&lt;/p&gt;

&lt;p&gt;I'm currently within every free tier on Sanity, Azure and Netlify by quite a long way. Side note, Netlify's free tier offers 300 build minutes per month. The site takes around 2 minutes to build each day, which is around 60 build minutes used each month. It'll be interesting to see how this build time goes up in a year when potentially thousands more links have been added.&lt;/p&gt;

&lt;p&gt;And that's it, that's how I built &lt;a href="https://webdesignrepo.com/" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt; in 17 days. In reality, this was spread across about 6-8 weeks as I have a full time job and there were also plenty of days where I'd only do 15-30 minutes work, but largely it was just 17 full days.&lt;/p&gt;




&lt;p&gt;How it looks today:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsbvevpsgsdtvpj1c3jxi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fsbvevpsgsdtvpj1c3jxi.png" alt="webdesignrepo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://webdesignrepo.com/" rel="noopener noreferrer"&gt;webdesignrepo&lt;/a&gt; - check it out for links on javascript, react, css, design and all things web dev!&lt;/p&gt;

</description>
      <category>gatsby</category>
      <category>react</category>
      <category>netlify</category>
      <category>javascript</category>
    </item>
    <item>
      <title>React 16 and 16.2 Overview - Fragments, Portals and Error Boundaries </title>
      <dc:creator>Ben Mildren</dc:creator>
      <pubDate>Thu, 21 Dec 2017 00:00:00 +0000</pubDate>
      <link>https://forem.com/mildrenben/react-16-and-162-overview---fragments-portals-and-error-boundaries-49</link>
      <guid>https://forem.com/mildrenben/react-16-and-162-overview---fragments-portals-and-error-boundaries-49</guid>
      <description>

&lt;p&gt;React 16 (and 16.2) adds some nice quality of life changes along with some performance gains.&lt;/p&gt;

&lt;h2&gt;Return types and Fragments&lt;/h2&gt;

&lt;p&gt;There's a whole slew of new return types in the render method.&lt;/p&gt;

&lt;p&gt;You can now return a string or number.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Often you end up wrapping a group of items in a &lt;code&gt;div&lt;/code&gt; or &lt;code&gt;span&lt;/code&gt; tag because React requires a wrapping element. React 16 introduced the ability to return arrays of items. &lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'a'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'b'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'c'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;,&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'d'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"Some words"&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But that kind of sucks as you need to add a key to each item, seperate each item by a comma and text must be wrapped in quotes. Yuck.&lt;/p&gt;

&lt;p&gt;React 16.2 builds on &lt;code&gt;React.Fragment&lt;/code&gt; to make a really nice way to wrap a group of items without the extra DOM node.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Fragment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'react'&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/Fragment&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There is also a shorthand way of writing &lt;code&gt;Fragment&lt;/code&gt; which doesn't require the import.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'react'&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This does look a little funky I'll admit, but I think once we've gotten used to it we won't know how we lived without it! Babel will support the &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; shorthand syntax in v7. See this &lt;a href="https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html"&gt;blog post&lt;/a&gt; for support in various tools. You can use the imported &lt;code&gt;Fragment&lt;/code&gt; component right now on Babel 6.x.&lt;/p&gt;

&lt;p&gt;One thing to note is that you still need to key &lt;code&gt;Fragment&lt;/code&gt;s when you map over data and such. The shorthand &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; does not accept the &lt;code&gt;key&lt;/code&gt; attribute unfortunately.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Fragment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'react'&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;{[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Fragment&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;hello&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/span&amp;gt;&lt;/span&gt;
                &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;world&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/span&amp;gt;&lt;/span&gt;
            &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/Fragment&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;))}&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/Fragment&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above code will produce an HTML output of this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;world 1&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;world 2&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;world 3&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Finally no more wrappers cluttering our DOM 🎉&lt;/p&gt;

&lt;h2&gt;Error Handling&lt;/h2&gt;

&lt;p&gt;Prior to React 16, when something went wrong with a component the whole application could crash and it was only visible in the console. That's why packages like &lt;a href="https://www.npmjs.com/package/redbox-react"&gt;redbox-react&lt;/a&gt; get over a million downloads a month!&lt;/p&gt;

&lt;p&gt;To solve this issue, we now have Error Boundaries using a new &lt;code&gt;componentDidCatch&lt;/code&gt; lifecycle event.&lt;/p&gt;

&lt;p&gt;You can wrap potentially breaking components in Error Boundaries and then configure them to show fallback UI if they do break.&lt;/p&gt;

&lt;p&gt;I modified a component that the official React blog supplies for an Error Boundary that will work in basically any app.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'react'&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'prop-types'&lt;/span&gt;

&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt; &lt;span class="kr"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kr"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hasError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;componentDidCatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Display fallback UI&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;hasError&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="c1"&gt;// You can also log the error to an error reporting service&lt;/span&gt;
        &lt;span class="c1"&gt;// Remove this if you have no error logging&lt;/span&gt;
        &lt;span class="nx"&gt;logErrorToMyService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errorMessage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// You can render any custom fallback UI&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/h1&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;defaultProps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Something went wrong.'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;propTypes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oneOfType&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
        &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arrayOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;
    &lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nx"&gt;isRequired&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropTypes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You then just wrap that around anything you think will fail.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;ErrorBoundary&lt;/span&gt; &lt;span class="nx"&gt;errorMessage&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'This component is not working properly'&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UnstableComponent&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/ErrorBoundary&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/div&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a-ZRN2Y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.imgur.com/6YItkVZ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a-ZRN2Y6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://i.imgur.com/6YItkVZ.gif" alt="ErrorBoundaries in action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember we can customise the UI, it's not just a message. So you could have some really cool fallback content for components.&lt;/p&gt;

&lt;p&gt;Things to note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;componentDidCatch&lt;/code&gt; works just like a regular old &lt;code&gt;catch {}&lt;/code&gt; block&lt;/li&gt;
&lt;li&gt;Error Boundaries must be class components&lt;/li&gt;
&lt;li&gt;Error Boundaries can only catch errors from their children, not errors from themselves&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Portals&lt;/h2&gt;

&lt;p&gt;Portals provide us with the ability to render things in other DOM nodes outside of the parents scope.&lt;/p&gt;

&lt;p&gt;This opens up some really cool possibilites for things like modals, dialog boxes, tooltips etc.&lt;/p&gt;

&lt;p&gt;I've seen many different systems for modals in React across many projects and I never feel like anyone has gotten in right, and that's likely because React didn't have the tools to do it right. Now with Portals we might be able to solve this problem. There's no more passing a function all the way through your React tree or using context.&lt;/p&gt;

&lt;p&gt;Portals can be used with the simple &lt;code&gt;ReactDOM.createPortal(child, container)&lt;/code&gt; function.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'react'&lt;/span&gt;
&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="nx"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'react-dom'&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;Through&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;portal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="err"&gt;/p&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ContactScreen&lt;/span&gt; &lt;span class="kr"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kr"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nav&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'nav'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createPortal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nx"&gt;Bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nav&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;child&lt;/code&gt; can be any valid React component and &lt;code&gt;container&lt;/code&gt; can be any DOM node.&lt;/p&gt;

&lt;p&gt;When using styled components or any other css in js system, you're classnames will end up being all mangled strings. It might be worth adding an ID to these components so you can portal to them should you need it.&lt;/p&gt;

&lt;p&gt;Of course, this isn't just reserved for existing DOM nodes. You can create one on the fly and insert it yourself into the DOM.&lt;/p&gt;

&lt;h2&gt;Custom DOM attributes&lt;/h2&gt;

&lt;p&gt;Previously, you could only use DOM attributes that actually existed, along with &lt;code&gt;aria-&lt;/code&gt; and &lt;code&gt;data-&lt;/code&gt; prefixed attributes. Now you can use any custom attribute and it'll get passed through to the real DOM element.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'bar'&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;Server Side Rendering&lt;/h2&gt;

&lt;p&gt;Server side rendering is not something I've used personally before, so I won't try to act like I know a lot about it. We did use it at a previous company I worked for, but I wasn't involved in the process. So here's a &lt;a href="https://hackernoon.com/whats-new-with-server-side-rendering-in-react-16-9b0d78585d67"&gt;really good article about what's changed in SSR in React 16&lt;/a&gt;. (TLDR: it's more performant)&lt;/p&gt;

&lt;h2&gt;Miscellaneous&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;It got smaller. React + React DOM is now ~30% smaller than before.&lt;/li&gt;
&lt;li&gt;They changed the license to MIT 🎉&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/blog/2017/09/26/react-v16.0.html"&gt;React 16 official blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://reactjs.org/blog/2017/11/28/react-v16.2.0-fragment-support.html"&gt;React 16.2 official blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>guide</category>
    </item>
    <item>
      <title>Maps in ES6 - A Quick Guide </title>
      <dc:creator>Ben Mildren</dc:creator>
      <pubDate>Mon, 11 Dec 2017 00:00:00 +0000</pubDate>
      <link>https://forem.com/mildrenben/maps-in-es6---a-quick-guide-35pk</link>
      <guid>https://forem.com/mildrenben/maps-in-es6---a-quick-guide-35pk</guid>
      <description>

&lt;h2&gt;Overview&lt;/h2&gt;

&lt;p&gt;Maps and Sets often get lumped together in articles. They're both new ES6 collection types with similar interfaces but that's where the similarities stop. So it makes sense to have two separate articles on them.&lt;/p&gt;

&lt;p&gt;Maps are like the love child of Arrays and Objects with a nice and sane interface. &lt;/p&gt;

&lt;p&gt;You can instantiate one like so:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In my last article on &lt;a href="https://dev.to/mildrenben/symbols-in-es6---a-quick-guide-dhm"&gt;Symbols&lt;/a&gt; we looked at how Objects could use either Strings or Symbols as keys. Well Maps can use any type of data as a key. Use the &lt;code&gt;.set()&lt;/code&gt; method to add key value pairs.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;

&lt;span class="c1"&gt;// as `this` is returned, we can chain the set methods&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'one'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'nothing'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can also pass the constructor a 2D iterable when creating a Map.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'nada'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To retrieve items from a Map use the &lt;code&gt;.get()&lt;/code&gt; method.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'hello'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Unlike Objects (but more like Arrays), Maps have a handy &lt;code&gt;.size&lt;/code&gt; property.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Maps check references to Objects for equality, so using Object literals is a bad idea as you won't be able to retrieve the values.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;({},&lt;/span&gt; &lt;span class="sb"&gt;`you'll never catch me`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;There are a number of other useful methods Maps supply.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;zoe&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Zoe'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'hey'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'nine'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;zoe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;23&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;// .has checks if the collection contains a key&lt;/span&gt;
&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;proptype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;


&lt;span class="c1"&gt;// .delete simply deletes an item&lt;/span&gt;
&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;// 2&lt;/span&gt;


&lt;span class="c1"&gt;// .clear deletes all values&lt;/span&gt;
&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;Map API Summary&lt;/h3&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;Usage&lt;/h2&gt;

&lt;p&gt;One fantastic advantage Maps have over Objects is how you can iterate over them. They're built to be iterated over with baked in methods like &lt;code&gt;.forEach&lt;/code&gt; and an iterator protocol for use with &lt;code&gt;for..of&lt;/code&gt; loops.&lt;/p&gt;

&lt;p&gt;They also preserve their order, unlike Objects and more like Arrays. So you can be sure everything is in the correct order.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'first'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'second'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'third'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;thisArg&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; 
&lt;span class="c1"&gt;// first 1&lt;/span&gt;
&lt;span class="c1"&gt;// second 2&lt;/span&gt;
&lt;span class="c1"&gt;// third 3&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;for..of&lt;/code&gt; loop returns each item (including both key and value), not just each value like you might expect.&lt;/p&gt;





&lt;p&gt;You can use destructuring to separate the values.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// 1 'first'&lt;/span&gt;
&lt;span class="c1"&gt;// 2 'second'&lt;/span&gt;
&lt;span class="c1"&gt;// 3 'third'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Just like with Objects we get access to &lt;code&gt;.keys()&lt;/code&gt;, &lt;code&gt;.values()&lt;/code&gt; and &lt;code&gt;.entries()&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt;
&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 1, 2, 3&lt;/span&gt;

&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt;
&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 'first', 'second', 'third'&lt;/span&gt;

&lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt;
&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// [1, 'first'], [2, 'second'], [3, 'third']&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These methods all return iterator objects. As they all conform to the iterator protocol, they can be used with &lt;code&gt;for..of&lt;/code&gt;, like a generator or using the &lt;code&gt;...&lt;/code&gt; spread operator.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;span class="c1"&gt;// 2&lt;/span&gt;
&lt;span class="c1"&gt;// 3&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: [1, 'first'], done: false }&lt;/span&gt;
&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: [2, 'second'], done: false }&lt;/span&gt;
&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: [3, 'third'], done: false }&lt;/span&gt;
&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// { value: undefined, done: true }&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'first', 'second', 'third'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;All of the above iteration methods make for a much more well rounded approach to iterating over a key value store, with a wealth of methods and consistent order; considerably better than on an Object.&lt;/p&gt;




&lt;p&gt;A great use case for Maps is the potential to add metadata to existing objects or attaching some extra data to immutable objects. Symbols are also very good for this, &lt;a href="https://dev.to/mildrenben/symbols-in-es6---a-quick-guide-dhm"&gt;see my previous article&lt;/a&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dataObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Zoe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Roman'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mapObjects&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nx"&gt;dataObjects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;mapObjects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}))&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;mapObjects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;dataObjects&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="c1"&gt;// [{ name: 'Ben', age: 25 }, { created: Sun Dec 17 2017 11:57:52 GMT+0000 (GMT) }]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;






&lt;h3&gt;Should I use a Map or an Object?&lt;/h3&gt;

&lt;p&gt;After seeing all that Maps can do, you might be thinking: "Will I ever need to use plain old Objects again?"&lt;/p&gt;

&lt;p&gt;Let's look at the pros and cons of each:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pros&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ordered. They stay in order like Arrays and have many iteration methods.&lt;/li&gt;
&lt;li&gt;Objects (or any other type) as keys. Having objects as keys can be super powerful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cons&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Loses &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype"&gt;a lot of Object methods&lt;/a&gt;. Most are very rarely used, but some are handy.&lt;/li&gt;
&lt;li&gt;No fast dot notation, which means no destructuring.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, if you need to iterate over your object or you want keys that aren't strings, your only option is Maps. If you know the shape of your object and expect it to be static (not adding or removing properties) then an Object might be best.&lt;/p&gt;

&lt;h2&gt;Details &amp;amp; Caveats&lt;/h2&gt;

&lt;h3&gt;What is equal?&lt;/h3&gt;

&lt;p&gt;Maps use something called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness"&gt;SameValueZero&lt;/a&gt; to determine if a Map has a key.&lt;/p&gt;

&lt;p&gt;SameValueZero is very similar to === but has 2 notable differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NaN&lt;/code&gt; is equal to &lt;code&gt;NaN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+0&lt;/code&gt; is equal to &lt;code&gt;-0&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 'hello'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;Non-existant keys&lt;/h3&gt;

&lt;p&gt;When looking up a key that doesn't exist, &lt;code&gt;undefined&lt;/code&gt; is returned. You'll need to be aware of this if you might be expecting a return value of &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'notAKey'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;Building from Objects&lt;/h3&gt;

&lt;p&gt;Object has a handy &lt;code&gt;.entries()&lt;/code&gt; method which returns the 2D array structure needed for a Map.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;entries&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [ ['name', 'Ben'], ['age', 25] ]&lt;/span&gt;
&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;Weakmaps&lt;/h3&gt;

&lt;p&gt;Despite being in the Details &amp;amp; Caveats section, WeakMaps are not trivial at all! (I just figured this would be the best place to put them)&lt;/p&gt;

&lt;p&gt;WeakMaps are a seperate data type to Maps. Just like their non-weak counterparts except they allow Javascript to remove their keys from memory if required and the keys &lt;em&gt;must&lt;/em&gt; be objects.&lt;/p&gt;

&lt;p&gt;They have a very similar api to Maps, with a few methods removed. These are all the methods WeakMaps have:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;WeakMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
&lt;span class="nx"&gt;WeakMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
&lt;span class="nx"&gt;WeakMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;
&lt;span class="nx"&gt;WeakMap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Put simply, WeakMaps are basically Maps which allow its own object keys to be garbage collected. This helps with memory leaks.&lt;/p&gt;

&lt;p&gt;If a Map has an object as a key and that object gets destroyed, the Map still retains that object as a key and it will stay in memory and won't be garbage collected as it's still "reachable" (don't worry, I'm going to write an article about how garbage collection works soon!). &lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// { age: 25 }&lt;/span&gt;

&lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// [ [{ name: 'Ben' }, { age: 25 }] ]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Conversely, if a WeakMap has a deleted object as a key, the WeakMap allows the garbage collector to remove that key and it's associated value.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WeakMap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="c1"&gt;// You can only use objects as keys, no primitives&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'primitive'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// TypeError: Invalid value used as weak map key&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// { age: 25 }&lt;/span&gt;

&lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;

&lt;span class="c1"&gt;// If there are no other reference to bar, it is removed as a key from foo&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, you might be wondering why I didn't show that the WeakMap doesn't retain the &lt;code&gt;bar&lt;/code&gt; key in the above example, and that's because I can't!&lt;/p&gt;

&lt;p&gt;WeakMaps do not have the tools to check, such as &lt;code&gt;.size&lt;/code&gt;, &lt;code&gt;.entries()&lt;/code&gt;, &lt;code&gt;.keys()&lt;/code&gt; or &lt;code&gt;.values()&lt;/code&gt;. And there is a good reason for this limitation: it wouldn't be &lt;em&gt;safe&lt;/em&gt; to show it.&lt;/p&gt;

&lt;p&gt;Javascript garbage collects at different times depending on what is executing, how intense current operations are, how much their is to collect, etc. Each Javascript engine handles these things slightly different too. So, although we know the WeakMaps key will be removed by the garbage collector, we do not know exactly when that will run. So it's not safe to use things like &lt;code&gt;.size&lt;/code&gt; which might tell us we have 1 item one moment and 0 the next due to garbage collection running in the background. &lt;/p&gt;

&lt;h4&gt;Where to use WeakMaps over Maps&lt;/h4&gt;

&lt;p&gt;WeakMaps won't see a ton of usage but there will be niche cases where they come in handy.&lt;/p&gt;

&lt;p&gt;One potential use case would be in state management where you need an object as a key. Most larger apps have a dedicated library for state management like Redux or Vuex. But maybe for a smaller app, if you were to roll your own state management system it might be handy to use WeakMaps there. Storing objects as keys, but also allowing those object to be garbage collected should they not be required anymore could be quite powerful.&lt;/p&gt;




&lt;p&gt;There is also the possibility of using WeakMaps for private data.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;keepOut&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WeakMap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kr"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;keepOut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;keepOut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;me&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Ben'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;me&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="c1"&gt;// { name: 'Ben' }&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As the instance of Person is stored as the key in the WeakMap, the data cannot be accessed without having that instance of Person.&lt;/p&gt;




&lt;p&gt;I mentioned above about using Maps to add metadata to objects or simply extend objects that couldn't be extended. WeakMaps are very handy for doing this with DOM elements.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myH1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'h1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myImg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'img'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;domElems&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;myH1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;created&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;myImg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;someExtraData&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'foo'&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you can track extra data along with the DOM elements and the WeakMap will allow them to be garbage collected when the DOM elements are no longer needed!&lt;/p&gt;


</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>guide</category>
    </item>
    <item>
      <title>Symbols in ES6 - A Quick Guide </title>
      <dc:creator>Ben Mildren</dc:creator>
      <pubDate>Thu, 07 Dec 2017 00:00:00 +0000</pubDate>
      <link>https://forem.com/mildrenben/symbols-in-es6---a-quick-guide-dhm</link>
      <guid>https://forem.com/mildrenben/symbols-in-es6---a-quick-guide-dhm</guid>
      <description>

&lt;h2&gt;Overview&lt;/h2&gt;

&lt;p&gt;Symbols are a new primitive type introduced in ES6.&lt;/p&gt;

&lt;p&gt;Symbols are completely unique identifiers. Just like its primitive counterparts, they can be created using the factory function &lt;code&gt;Symbol()&lt;/code&gt; which returns a &lt;code&gt;Symbol&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The two variables below, &lt;code&gt;foo&lt;/code&gt; and &lt;code&gt;bar&lt;/code&gt; are not the same, they are both unique. Imagine a really long random string is return by each &lt;code&gt;Symbol()&lt;/code&gt; call.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="c1"&gt;// I imagine Symbols looking like this 'NqkvK1kq7q#R99l9&amp;amp;7YH*@7wa8cFJc'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It takes an optional description argument, used only for debugging purposes.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'foo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Unlike its counterparts (Boolean, Number and String), Symbols do not have a literal nor can they be used as a constructor.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;// TypeError: Symbol is not a constructor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;Usage&lt;/h2&gt;

&lt;p&gt;Symbols primary use case is for making &lt;em&gt;private&lt;/em&gt; object properties, which can be only of type String or Symbol (for those curious, Numbers are automatically converted to Strings).&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sym&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s1"&gt;'someValue'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// 'someValue'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Using Symbols for object properties is handy for &lt;em&gt;hiding&lt;/em&gt; certain properties that might name clash with other libraries. &lt;/p&gt;




&lt;p&gt;They're also very useful for defining metadata on an object, as Symbols are not enumarable and as such they are &lt;em&gt;not&lt;/em&gt; iterated over when using a &lt;code&gt;for...of&lt;/code&gt; loop and other functions that return object properties.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sym&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s1"&gt;'someHiddenMetadata'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Ben, 25&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOwnPropertyNames&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Ben, 25&lt;/span&gt;

&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Ben, 25&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Symbols as object properties are not completely hidden though, hence why I've been italicising &lt;em&gt;hidden&lt;/em&gt; in this article. You can still access Symbols by using the following methods:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getOwnPropertySymbols&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Symbol()&lt;/span&gt;

&lt;span class="nb"&gt;Reflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ownKeys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Symbol()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So, they're not entirely private, but they are skipped in common iteration cycles.&lt;/p&gt;




&lt;p&gt;Just as you'd expect they can also be used for any object property name, including methods.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'method'&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;h3&gt;Usage without objects&lt;/h3&gt;

&lt;p&gt;Although the main application for Symbols seems to be as object property names, they could have value elsewhere, most notably as a replacement for Strings in constants.&lt;/p&gt;

&lt;p&gt;Lots of projects have a set of constants that looks something like this:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ARTICLE1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ARTICLE1'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ARTICLE2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ARTICLE2'&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ARTICLE3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ARTICLE3'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;These constants might then be used in another file making a request as such:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;'./constants'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getRequestURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;switch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Standard articles&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARTICLE1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// do stuff&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`https://api.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARTICLE1&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARTICLE2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// do stuff&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`https://api.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARTICLE2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ARTICLE3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// do stuff&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`https://api.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ARTICLE3&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Articles written by users get handled here&lt;/span&gt;
    &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// do stuff&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`https://api.com/userGeneratedContent/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    }
  }
}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Obviously the above is quite a contrived example but you get the picture. A lot of frontend apps are structured similarly to this.&lt;/p&gt;

&lt;p&gt;Let's imagine that by chance someone named the title of their article 'ARTICLE1'. It would not get to the &lt;code&gt;default&lt;/code&gt; function of the switch statement where it wants to be, it would be intercepted above. You can see that because our constants are not unique, they can interact in unexpected ways.&lt;/p&gt;

&lt;p&gt;The solution to this issue is using Symbols as constants.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ARTICLE1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ARTICLE1'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ARTICLE2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ARTICLE2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ARTICLE3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ARTICLE3'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now there is no possible way these constants can conflict with another constant.&lt;/p&gt;

&lt;h2&gt;Details &amp;amp; Caveats&lt;/h2&gt;

&lt;h3&gt;Global Symbols&lt;/h3&gt;

&lt;p&gt;Global Symbols seemingly go against the whole point of Symbols: they're not unique. But they do have a purpose.&lt;/p&gt;

&lt;p&gt;A Global Symbol Registry exists where you can store and access Global Symbols. You can use the &lt;code&gt;Symbol.for(key)&lt;/code&gt; method to both create and access Global Symbols.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// If the Symbol does not exist, it's created&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// The Symbol exists, so it is returned&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that the &lt;code&gt;key&lt;/code&gt; here is not an optional description like in regular Symbols, it is an identifier.&lt;/p&gt;

&lt;p&gt;You can do a reverse look up for Global Symbols if you have the Symbol itself and want the key.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'someKey'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keyFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// someKey&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Global Symbols exist across &lt;em&gt;realms&lt;/em&gt;. A realm is a context in which code exists, almost like a scope. Modules, global variables etc. all exist &lt;em&gt;within&lt;/em&gt; realm. Each frame in a browser is in its own realm, so iFrames have a different context to your main frame. Global Symbols actually do exist across realms and can be used between them.&lt;/p&gt;

&lt;h3&gt;"Well Known" Symbols&lt;/h3&gt;

&lt;p&gt;There are a number of "Well Known" Symbols baked right into javascript and they all have specific functions. &lt;/p&gt;

&lt;p&gt;The most useful of these so called "Well Known" Symbols is &lt;code&gt;Symbol.iterator&lt;/code&gt;, which allows us to make our own objects iterable. The &lt;code&gt;for...of&lt;/code&gt; loop calls &lt;code&gt;Symbol.iterator&lt;/code&gt; to iterate over a set of values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator"&gt;MDN&lt;/a&gt; provides this simple example to show how you'd use &lt;code&gt;Symbol.iterator&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;myIterable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="nx"&gt;myIterable&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;myIterable&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;// [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can see a full list of "Well Known" Symbols &lt;a href="https://tc39.github.io/ecma262/#sec-well-known-symbols"&gt;right here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;No auto conversion to String&lt;/h3&gt;

&lt;p&gt;Unlike many other types, Symbols do not auto convert to a String. You may not have even noticed this was happening for other types, but think about when you alert() a Number, or alert() an Array. They get auto converted to a string.&lt;/p&gt;

&lt;p&gt;Symbols don't support this. You must explicitly call the &lt;code&gt;.toString()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;This funcionality is here to help us as usually they should not be converted.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sym&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;sym&lt;/span&gt;
&lt;span class="c1"&gt;// TypeError: Cannot convert a Symbol value to a string&lt;/span&gt;

&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// TypeError: Cannot convert a Symbol value to a string&lt;/span&gt;

&lt;span class="nx"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// Symbol()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Due to this, you need to use square brackets within object literals, like so &lt;code&gt;const foo = { [Symbol()]: 'hey' }&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;When are they copied?&lt;/h3&gt;

&lt;p&gt;Symbols are copied in both &lt;code&gt;Object.assign&lt;/code&gt; and the object spread operator &lt;code&gt;{ ... }&lt;/code&gt;.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sym&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hey'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;sym&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="s1"&gt;'a'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// { Symbol('hey'): 'a' }&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="c1"&gt;// { Symbol('hey'): 'a' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;Further Reading&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://2ality.com/2014/12/es6-symbols.html"&gt;Symbols in ECMAScript 6 by 2ality&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/"&gt;Metaprogramming in ES6 by Keith Cirkel&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>guide</category>
    </item>
    <item>
      <title>Sets in ES6 - A Quick Guide </title>
      <dc:creator>Ben Mildren</dc:creator>
      <pubDate>Wed, 18 Jan 2017 00:00:00 +0000</pubDate>
      <link>https://forem.com/mildrenben/sets-in-es6---a-quick-guide-3mmk</link>
      <guid>https://forem.com/mildrenben/sets-in-es6---a-quick-guide-3mmk</guid>
      <description>

&lt;h2&gt;Overview&lt;/h2&gt;

&lt;p&gt;Sets are a new data type in ES6.&lt;/p&gt;

&lt;p&gt;They're similar to Arrays with one major difference, each value must be unique. They have an API that's very similar to &lt;a href="https://dev.to/mildrenben/maps-in-es6---a-quick-guide-35pk"&gt;Maps&lt;/a&gt;. They're a little bit simpler than Maps though so don't worry!&lt;/p&gt;

&lt;p&gt;Sets are instantiated as you'd expect: either empty or with an iterable.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can add to the Set with the &lt;code&gt;.add()&lt;/code&gt; method. As it returns &lt;code&gt;this&lt;/code&gt;, you can chain them.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hey there'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'yo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can also check to see if a value exists with &lt;code&gt;.has()&lt;/code&gt; method.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'yo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'greetings'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You may have noticed a pattern with this API in comparison to Maps now and removing items is no different with the &lt;code&gt;.delete()&lt;/code&gt; and &lt;code&gt;.clear()&lt;/code&gt; methods. &lt;code&gt;.remove()&lt;/code&gt; returns a boolean depending on if the value existed or not.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'yo'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'greetings'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The static property &lt;code&gt;.size&lt;/code&gt; returns the amount of items in the Set.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="nx"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;Set API Summary&lt;/h3&gt;

&lt;p&gt;There a few other methods for iteration which we'll cover in the next section, but these are the basics.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;Usage&lt;/h2&gt;

&lt;h3&gt;Special snowflake&lt;/h3&gt;

&lt;p&gt;Remember the big difference between Arrays and Sets? In a Set, a value cannot occur more than once. So each value is definitely unique. This immediately has some fantastic use cases. I know I've certainly reached for Lodash's &lt;code&gt;_.uniq&lt;/code&gt; functions before, well now you don't need to.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mySet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uniqueArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;mySet&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is pretty powerful, although it would be nice for Arrays to have a built in method for this function. (Side note: &lt;code&gt;...&lt;/code&gt; and &lt;code&gt;Array.from&lt;/code&gt; are the slowest methods to do this, with &lt;code&gt;for...of&lt;/code&gt; being the quickest on modern browsers. This is a real shame as the first 2 are so much cleaner. &lt;a href="https://jsperf.com/set-iterator-vs-foreach/4"&gt;Source&lt;/a&gt;)&lt;/p&gt;

&lt;h3&gt;Iteration&lt;/h3&gt;

&lt;p&gt;Something not immediately obvious is that you cannot retrieve values from a Set using the Array index method &lt;code&gt;[n]&lt;/code&gt;. This is because Sets are not indexed.&lt;/p&gt;

&lt;p&gt;The only way to use the values in a Set is through iteration, and for this reason they're stored in insertion order. You can use the &lt;code&gt;.forEach()&lt;/code&gt; method to iterate over a Set.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;val2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;thisArg&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="c1"&gt;// 1, 2, 3, 4&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Strangely, the callback you pass to &lt;code&gt;.forEach()&lt;/code&gt; accepts 3 arguments. Both of the first 2 args are the same thing: the value. I imagine they duplicated the value to conform with the same API that Maps have (where they have a key and a value). The third value is the current Set you're iterating over. A number of methods have this argument, and I've never figured out why (please comment if you know why). Finally, you can optionally set the value of &lt;code&gt;this&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Sets also use the iterator protocol which allows you to use Sets with &lt;code&gt;for...of&lt;/code&gt; loops.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1, 2, 3, 4, undefined&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;Maps have a &lt;code&gt;.keys()&lt;/code&gt;, a &lt;code&gt;.values()&lt;/code&gt; and a &lt;code&gt;.entries()&lt;/code&gt; method. Sets do not have keys so they do not have a &lt;code&gt;.keys()&lt;/code&gt; method, but they do have the other two.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;vals&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// SetIterator {1,2,3,4}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;vals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1, 2, 3, 4&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt; &lt;span class="nx"&gt;iterator&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// SetIterator {1,2,3,4}&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;ent&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;ents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// [1, 1], [2, 2], [3, 3], [4, 4]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;






&lt;h3&gt;Should I use an Set or a Array?&lt;/h3&gt;

&lt;p&gt;When we asked a similar question for &lt;a href="https://dev.to/mildrenben/maps-in-es6---a-quick-guide-35pk"&gt;Maps and Objects&lt;/a&gt;, Maps seemed like the better choice quite often, but it was a pretty good split on pros and cons for the pair of them. Unfortunately for Set, I think the answer here is much more one sided. &lt;/p&gt;

&lt;p&gt;Arrays are &lt;em&gt;almost&lt;/em&gt; always more useful in every day life. Sets having only unique items within them is definitely helpful, I just don't see many more things that I'd honestly pick a Set for over an Array. Sure, there are certain situations where Sets excel, but they're so few and far between that I'd reach for an Array basically every time.&lt;/p&gt;

&lt;p&gt;That said, do read the details and caveats below as there are definitely certain situations where a Set is more performant or more practical.&lt;/p&gt;

&lt;h2&gt;Details &amp;amp; Caveats&lt;/h2&gt;

&lt;h3&gt;What is equal?&lt;/h3&gt;

&lt;p&gt;Like Maps, Sets use something called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness"&gt;SameValueZero&lt;/a&gt; to determine if a Set has a value.&lt;/p&gt;

&lt;p&gt;SameValueZero is very similar to === but has 2 notable differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NaN&lt;/code&gt; is equal to &lt;code&gt;NaN&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+0&lt;/code&gt; is equal to &lt;code&gt;-0&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;Using Array methods&lt;/h3&gt;

&lt;p&gt;Converting between Sets and Arrays is so easy, using Array methods on Sets is easy!&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sortedArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sortedSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sortedArray&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// 1, 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or even shorted (but slightly less clear)&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sortedSet&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="c1"&gt;// 1, 2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;WeakSet&lt;/h3&gt;

&lt;p&gt;WeakSets are a separate data type, but they are very similar to Sets.&lt;/p&gt;

&lt;p&gt;This is the full WeakSet API:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nx"&gt;WeakSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;
&lt;span class="nx"&gt;WeakSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;
&lt;span class="nx"&gt;WeakSet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;boolean&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As we can see, this just like the Set API but with a few things removed. &lt;/p&gt;

&lt;p&gt;It is worth noting that &lt;code&gt;WeakSet.prototype.clear()&lt;/code&gt; used to be apart of the spec, but has been removed. Although this may work with certain browsers, you should not use this as it will be unsupported soon.&lt;/p&gt;

&lt;p&gt;There are two fundamental differences between WeakSets and Sets:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can only add objects to WeakSets, no primitives&lt;/li&gt;
&lt;li&gt;WeakSets allow their values to be garbage collected&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's see the first point in action: no primitives.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WeakSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// TypeError: Invalid value used in weak set&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'hello'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// TypeError: Invalid value used in weak set&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt; &lt;span class="c1"&gt;// ✅&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's straightforward, but the second point is a little harder to grasp without good understanding of how garbage collection works in modern browsers (I'll be writing a blog about that shortly).&lt;/p&gt;

&lt;p&gt;Browsers hold on to objects in memory for as long as they think that object is "reachable". If you were to store a value in a Set, and that value became unreachable anywhere else, it'll still be reachable in the Set and thus the garbage collector will not remove it from memory.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;someObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someObj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;someObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// 1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example, &lt;code&gt;foo&lt;/code&gt; holds on to the value and stops it being garbage collected. WeakSets hold on to their values &lt;em&gt;weakly&lt;/em&gt; and will allow garbage collectors to remove them.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WeakSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;someObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someObj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;someObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Unfortunately, there is no way to check that the object has been removed from &lt;code&gt;foo&lt;/code&gt;, but rest assured it will be once a garbage collection happens.&lt;/p&gt;

&lt;p&gt;WeakSets have such a tiny API that I cannot see many every day use cases for them. There is potentially some very niche cases such as marking certain items. Say you need to know if you've marked an item that you've previously iterated over. You could add another property to the object or you could add that item to a WeakSet.&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;WeakSet&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;someArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Ben'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Zoe'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Roman'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;someArr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Flipping a coin&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;random&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// You can check later if that value got a heads or tails&lt;/span&gt;
&lt;span class="nx"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someArr&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Assuming that item becomes unreachable in the future, it will also be removed from the WeakSet.&lt;/p&gt;

&lt;p&gt;This all feels like a stretch to me if I'm honest. It just feels like I would basically never reach for a WeakSet. I'd love for someone to comment and let me know some use cases for WeakSets.&lt;/p&gt;


</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
