<?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>DEV Community: EmNudge</title>
    <description>The latest articles on DEV Community by EmNudge (@emnudge).</description>
    <link>https://dev.to/emnudge</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%2F180166%2Fce674fc7-fef0-43ec-a3ba-3c38547b1d04.png</url>
      <title>DEV Community: EmNudge</title>
      <link>https://dev.to/emnudge</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/emnudge"/>
    <language>en</language>
    <item>
      <title>Understanding Loose Equality In JavaScript</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Wed, 06 Jan 2021 17:54:52 +0000</pubDate>
      <link>https://dev.to/emnudge/understanding-loose-equality-in-javascript-21c8</link>
      <guid>https://dev.to/emnudge/understanding-loose-equality-in-javascript-21c8</guid>
      <description>&lt;p&gt;For those who prefer a more audiovisual form, a video almost identical to the article can be seen over here: &lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/V3vZSO4zpFs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Abstract Equality, or as I've titled this article "Loose Equality" is (I think) one of the most misunderstood topics in JavaScript. People know loose equality, the double equals (&lt;code&gt;==&lt;/code&gt;), to check if its operands are roughly equal to each other. The string &lt;code&gt;"55"&lt;/code&gt; and the number &lt;code&gt;55&lt;/code&gt; are &lt;em&gt;kind&lt;/em&gt; of the same thing, but not &lt;em&gt;strictly&lt;/em&gt; the same thing, with triple equals (&lt;code&gt;===&lt;/code&gt;). &lt;/p&gt;

&lt;p&gt;People usually advise against using loose equality. Personally? Well if JavaScript came out with a &lt;em&gt;**strict&lt;/em&gt;* strict mode* that removed loose equality, I wouldn't be too bothered. &lt;/p&gt;

&lt;p&gt;But there's a lot of misinformation out there and I thought it would be helpful to clean some of that up. Which is why I've been working on this topic for so long.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// loose equality vs strict equality&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;55&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;   &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;55&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;  &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Loose equality, in reality, is a process that tries to &lt;em&gt;implicitly coerce&lt;/em&gt; its operands to be the same type before passing it off to strict equal to give you the real result. &lt;em&gt;Implicit coercion&lt;/em&gt; by itself actually isn't too bad. It's used in many other languages and JavaScript programmers use it pretty often.&lt;/p&gt;

&lt;p&gt;In this example, we take advantage of &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Falsy" rel="noopener noreferrer"&gt;falsy and truthy values&lt;/a&gt; to check whether we should print out an array to the console. If the array exists and has a length property greater than 0, print it out.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// example of implicit coercion&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myArr&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;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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myArr&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;myArr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;My arr is: &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;myArr&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://developer.mozilla.org/en-US/docs/Glossary/Falsy" rel="noopener noreferrer"&gt;Falsy&lt;/a&gt; values include all the JavaScript values that will evaluate to &lt;code&gt;false&lt;/code&gt; when converted into a boolean.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&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;// -&amp;gt; false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&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;// -&amp;gt; false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&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="c1"&gt;// -&amp;gt; false&lt;/span&gt;
&lt;span class="nc"&gt;Boolean&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;// -&amp;gt; false&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Do not confuse this with abstract equality, however. Double equals often does &lt;strong&gt;not&lt;/strong&gt; rely on this system whatsoever. While using the exact same values, we get true for half only. I'm no statistician, but 50-50 looks like zero correlation to me.  &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;         &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;          &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt;         &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;
&lt;span class="kc"&gt;false&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;// -&amp;gt; false&lt;/span&gt;
&lt;span class="kc"&gt;false&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;// -&amp;gt; false&lt;/span&gt;
&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;  &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In fact, I would go so far as to say the concept of falsy values &lt;strong&gt;never&lt;/strong&gt; comes up within &lt;a href="https://www.ecma-international.org/ecma-262/11.0/index.html#sec-abstract-equality-comparison" rel="noopener noreferrer"&gt;abstract equality in the spec&lt;/a&gt;? What's the spec?&lt;/p&gt;

&lt;p&gt;The JavaScript specification is an esoteric document that instructs browsers on how JavaScript should work. Browsers all can code up the implementation themselves, but if you want to know how JavaScript works without digging through C++ code, this is the best place to look.&lt;/p&gt;

&lt;p&gt;The spec can often be pretty confusing, but &lt;a href="https://www.ecma-international.org/ecma-262/11.0/index.html#sec-abstract-equality-comparison" rel="noopener noreferrer"&gt;this particular section&lt;/a&gt; is actually kind of readable. It defines abstract equality as a list of steps and I think it's pretty cool. If you're ever wondering why null is loosely equal to undefined, this is why. Because it says so. There is no low-level reason why it must be that way - the discussion stops here. It works that way because the document says it should. &lt;/p&gt;

&lt;p&gt;While I can go through the document, I'm going to instead use a tool I've been working on to explain it a bit more simply - &lt;a href="https://emnudge.dev/abs-eq/" rel="noopener noreferrer"&gt;The Abstract Equality Stepper&lt;/a&gt;. I've written up the steps to roughly match spec. There are some minor changes in formatting to help with how my tool works, but it's essentially the same.&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%2Fei0a2ba0nj8mfo6feycb.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%2Fei0a2ba0nj8mfo6feycb.png" alt="preview of tool"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's punch in some examples we've just shown to explore how this works. &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; perhaps.&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%2Fbb3jewk7iol0unfmp88z.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%2Fbb3jewk7iol0unfmp88z.png" alt="Untitled (1)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(&lt;a href="https://emnudge.dev/abs-eq/#%22false%22,%220%22" rel="noopener noreferrer"&gt;View it here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;We can see that it declares either of the operands are a boolean, we convert the boolean to a number. Always. No matter what the other value is. &lt;/p&gt;

&lt;p&gt;Notice that it tells us to perform an abstract equality comparison, but these are the steps that &lt;strong&gt;define&lt;/strong&gt; what an abstract equality comparison &lt;strong&gt;is&lt;/strong&gt;. That's right, this is recursion. We restart with new values. Since the types are now equal, we chuck it off to a strict equality comparison which returns true since they're the same value.&lt;/p&gt;

&lt;p&gt;Notice that abstract equality &lt;strong&gt;uses&lt;/strong&gt; strict equality. &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%2Fznygxq5csiw3tc1fyyz2.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%2Fznygxq5csiw3tc1fyyz2.png" alt="Untitled (2)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So technically abstract equality must be less performant if the implementation matches the spec exactly. This is way too minor to matter in practice, but I thought it was interesting. &lt;/p&gt;

&lt;p&gt;Let's try &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;''&lt;/code&gt;. We convert the boolean to a number like last time, but now we're left with a number versus a string.&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%2Fhf0n4oomm2nq8ae643p8.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%2Fhf0n4oomm2nq8ae643p8.png" alt="Untitled (3)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;(&lt;a href="http://localhost:5000/#%22false%22,%22''%22" rel="noopener noreferrer"&gt;View it here&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;We convert the string to a number and then go to strict equality. We're converting to numbers a lot here. It's for good reason. Numbers can be thought of as the most primitive type. It's easy to compare number to number and it's essentially what we're doing when we compare anything else. Even when we compare using reference equality (like with 2 objects) we're comparing memory locations, which, as you might have guessed, are numbers. &lt;/p&gt;

&lt;p&gt;We can substitute &lt;code&gt;0&lt;/code&gt; for false for all of the other examples.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="mi"&gt;0&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;// -&amp;gt; false&lt;/span&gt;
&lt;span class="mi"&gt;0&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;// -&amp;gt; false&lt;/span&gt;
&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;  &lt;span class="c1"&gt;// -&amp;gt; false&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;&lt;code&gt;0&lt;/code&gt; isn't &lt;code&gt;NaN&lt;/code&gt; so that's gonna be false. And then there is no step to define &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;, so we get &lt;code&gt;false&lt;/code&gt; by &lt;strong&gt;default.&lt;/strong&gt; &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%2F1clwmxf45begn38pwg7n.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%2F1clwmxf45begn38pwg7n.png" alt="Untitled (4)"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Nothing to do with falsy values here. Just looking at steps and following the rules. &lt;/p&gt;

&lt;p&gt;With that out of the way, let's look at a common example of abstract equality weirdness - a real headscratcher. &lt;/p&gt;
&lt;h1&gt;
  
  
  WTFJS - The Headscratcher
&lt;/h1&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;  &lt;span class="c1"&gt;// -&amp;gt; true&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;This &lt;strong&gt;looks&lt;/strong&gt; paradoxical, but it actually makes sense. First, we convert the left array to a boolean. This &lt;strong&gt;does&lt;/strong&gt; involve the concept of falsy, but we haven't touched abstract equality yet, just expression evaluation. Since arrays aren't falsy, we would get &lt;code&gt;true&lt;/code&gt;, but we're using an exclamation mark, so we flip that and get &lt;code&gt;false&lt;/code&gt;. &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;


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

&lt;/div&gt;
&lt;p&gt;Since booleans always turn to numbers in this system, our operands are &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;[]&lt;/code&gt;. Now what?&lt;/p&gt;

&lt;p&gt;Well, now we find ourselves face to face with the magical &lt;a href="https://jsitor.com/5ktE3jQzt8" rel="noopener noreferrer"&gt;&lt;code&gt;ToPrimitive&lt;/code&gt;&lt;/a&gt;. This one is interesting. We can't just compare a primitive value and an object, we need 2 primitive values or 2 objects. We try turning our array into a primitive and out pops an empty string.&lt;/p&gt;

&lt;p&gt;(Note: a function is just a callable object. When we use the term &lt;code&gt;object&lt;/code&gt;, we include functions)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;0&lt;/code&gt; and &lt;code&gt;''&lt;/code&gt; means we turn the string into a number, which leads us to &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; which are equal.&lt;/p&gt;

&lt;p&gt;But how does &lt;code&gt;ToPrimitive&lt;/code&gt; work? What does it do?&lt;/p&gt;

&lt;p&gt;We can &lt;a href="https://www.ecma-international.org/ecma-262/11.0/index.html#sec-toprimitive" rel="noopener noreferrer"&gt;look at the spec again&lt;/a&gt;, but this time it's a little more difficult, so I've taken the liberty of converting it to plain JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="400" src="https://jsitor.com/embed/5ktE3jQzt8"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;If we're passed a primitive value, just return that. No need to convert a primitive to a primitive. &lt;/p&gt;

&lt;p&gt;Then we check for a &lt;code&gt;Symbol.toPrimitive&lt;/code&gt; property. This is a rather recent addition to JavaScript which allows you to define the &lt;code&gt;ToPrimitive&lt;/code&gt; behavior a bit more easily.&lt;br&gt;&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%2F9gvf9uq42aajigf4c147.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%2F9gvf9uq42aajigf4c147.png" alt="Untitled (4)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If such a method exists, we try to convert it to a number. How? We check for a &lt;code&gt;.valueOf&lt;/code&gt; property, which is what &lt;code&gt;Number&lt;/code&gt; calls. If you try adding your object to a number, it will try to look for this property and call it.&lt;/p&gt;

&lt;p&gt;If this property doesn't exist on your object or it itself returns an object, we try converting it to a string. Using, of course, the &lt;code&gt;.toString&lt;/code&gt; property. This is actually defined on all object by default, including arrays. If you don't touch your object then &lt;code&gt;ToPrimitive&lt;/code&gt; will return a string. For arrays, this means returning all its values as a comma-separated list. If it's empty, that's an empty string.&lt;/p&gt;

&lt;div class="highlight js-code-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;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;valueOf&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calling valueOf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;toString&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calling toString&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;👀&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;43&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`I see you &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;obj&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;(&lt;a href="https://twitter.com/emnudge/status/1345079883026857984" rel="noopener noreferrer"&gt;Note: string concatenation itself doesn't always call &lt;code&gt;.toString&lt;/code&gt;&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;And there's your explanation! &lt;/p&gt;

&lt;p&gt;But if you look a bit closer, you'll notice a few errors being thrown. Wait, does that mean...&lt;/p&gt;

&lt;p&gt;Yup! There are often times where just using double equals will throw an error instead of returning false. Let's create such a scenario right now. &lt;/p&gt;

&lt;h1&gt;
  
  
  Throwing Errors With Equality Checks
&lt;/h1&gt;

&lt;div class="highlight js-code-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;obj1&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="nx"&gt;toPrimitive&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="mi"&gt;45&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: number 45 is not a function&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We can also just make it a function, but return an object.&lt;/p&gt;

&lt;div class="highlight js-code-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;obj2&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="nx"&gt;toPrimitive&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Object&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: Cannot convert object to primitive value&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Or do the same with the other methods&lt;/p&gt;

&lt;div class="highlight js-code-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;obj3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Object&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj3&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: Cannot convert object to primitive value&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, we can't actually delete these methods on most objects. I mentioned earlier that all objects implement this by default. All objects of course inherit this method from the object prototype and we can't really delete that.&lt;/p&gt;

&lt;p&gt;However, it's possible to make an object with no prototype using &lt;code&gt;Object.create(null)&lt;/code&gt;. Since it has no prototype, it has no &lt;code&gt;valueOf()&lt;/code&gt; and no &lt;code&gt;toString()&lt;/code&gt; and thus it will throw an error if we compare it to a primitive. Magical!&lt;/p&gt;

&lt;div class="highlight js-code-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="nf"&gt;create&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="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught TypeError: Cannot convert object to primitive value&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;With that detour, let's close with the essence of this article - how to understand loose equality. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;When comparing 2 things of different types, it'll help to convert the more complex type to a simpler representation. If we can convert to a number, do that. If we're adding an object to the mix, get the primitive value and again try squeezing a number out of it. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; are loosely equal and that's that. &lt;/p&gt;

&lt;p&gt;If we get something like &lt;code&gt;Symbol()&lt;/code&gt; or we compare &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; with anything else by each other, we get &lt;code&gt;false&lt;/code&gt; &lt;strong&gt;by default&lt;/strong&gt;. &lt;code&gt;Symbol()&lt;/code&gt; actually has a &lt;code&gt;.toString()&lt;/code&gt; method, but it doesn't really matter. The spec says we get &lt;code&gt;false&lt;/code&gt;, so we get &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If we want to describe the steps in a bit of a simpler form, it looks something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;null equals undefined&lt;/li&gt;
&lt;li&gt;Number(string) == number&lt;/li&gt;
&lt;li&gt;BigInt(string) == bigint&lt;/li&gt;
&lt;li&gt;Number(boolean) == anything&lt;/li&gt;
&lt;li&gt;ToPrimitive(object) == anything&lt;/li&gt;
&lt;li&gt;BigInt(number) == bigint&lt;/li&gt;
&lt;li&gt;false&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Stay curious!&lt;/p&gt;

</description>
      <category>loose</category>
      <category>javascript</category>
      <category>ecma</category>
    </item>
    <item>
      <title>Deno - An Unfinished Beauty</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Mon, 26 Oct 2020 00:05:53 +0000</pubDate>
      <link>https://dev.to/emnudge/deno-an-unfinished-beauty-4bhn</link>
      <guid>https://dev.to/emnudge/deno-an-unfinished-beauty-4bhn</guid>
      <description>&lt;blockquote&gt;
&lt;h1&gt;
  
  
  2022 Update:
&lt;/h1&gt;

&lt;p&gt;My concerns around immaturity have long since been addressed since the 1.0 release. While issues around arm32 builds might still exist, my concerns around instability, ICU, npm-interop, and permissions have all been addressed. You may read this article as a lens into the time period when it was released as opposed to a modern look on the tooling.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is going to be a bit dense. I've been using Deno for a while now and I've been told it might be useful to publish my thoughts on it so far. I'll be jumping around a lot, going over its features, so don't expect a super philosophically consistent article. This is mostly an opinion piece based on my experiences.&lt;/p&gt;

&lt;p&gt;For those unaware, &lt;a href="https://deno.land/"&gt;Deno&lt;/a&gt; is a JavaScript runtime. &lt;/p&gt;

&lt;h1&gt;
  
  
  A What?
&lt;/h1&gt;

&lt;p&gt;The differences between a JavaScript runtime and an engine aren't super clear, but colloquially I've found it to be:&lt;/p&gt;

&lt;p&gt;JavaScript Runtime = JavaScript Engine + User-Facing Layer&lt;/p&gt;

&lt;p&gt;The user-facing layer would be both the included APIs and how you run your code. Chrome, Node.js, and Deno all use &lt;a href="https://v8.dev/"&gt;Google's V8 engine&lt;/a&gt; to actually run the code, but they have varying APIs and ways with which you set up your code to be executed. &lt;/p&gt;

&lt;p&gt;With Chrome you must include the script in an executed HTML file, with Node.js you use the &lt;code&gt;node&lt;/code&gt; binary and perhaps a &lt;code&gt;package.json&lt;/code&gt;, and with Deno you use the &lt;code&gt;deno&lt;/code&gt; binary with a bunch of flags to define security and features.&lt;/p&gt;

&lt;p&gt;As for their APIs, some things stay the same, while others might differ. All platforms implement the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/URL"&gt;URL API&lt;/a&gt; the same. All platforms allow for &lt;a href="https://developer.mozilla.org/en-US/docs/WebAssembly"&gt;WebAssembly&lt;/a&gt;, but the way your run WASM in the web differs from Deno and Node. Node and Deno both include (almost identical) &lt;a href="https://nodejs.org/api/path.html"&gt;path utilities&lt;/a&gt;, whereas the web does not. Deno and the web often include very similar APIs such as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket"&gt;WebSockets&lt;/a&gt;, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData"&gt;FormData&lt;/a&gt;, and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer"&gt;ArrayBuffer&lt;/a&gt;, whereas Node might have something vaguely similar or requires third-party libraries. The web also includes some very useful APIs such as &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API"&gt;Canvas&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/DOMParser"&gt;DOMParser&lt;/a&gt; which Deno and Node are forced to use third-party libraries for.&lt;/p&gt;

&lt;p&gt;But of course at the end of the day, they all run JavaScript. Deno is targeted at being a better version of Node, using the web and Node's faults as lessons to build from. It generally tries to match Web APIs where it can, but being a stand-alone binary, it can leverage a lot of power that a regular website cannot. &lt;/p&gt;

&lt;h1&gt;
  
  
  The Great
&lt;/h1&gt;

&lt;p&gt;With that general introduction, Deno has a lot of really nice Quality Of Life features. I'm going to separate them into categories because they'd be too much to tackle individually.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Standard Library
&lt;/h2&gt;

&lt;p&gt;This one isn't mentioned all that often, but Deno has a really nice &lt;a href="https://deno.land/std@0.74.0"&gt;standard library&lt;/a&gt;. It has a lot of helpful functions that really do feel like &lt;em&gt;extras&lt;/em&gt; rather than &lt;em&gt;necessities&lt;/em&gt;, but I don't mean that in a bad way. Where the web and node will be forced to use 3rd party libraries for many things, Deno has some great packages out of the box.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/datetime"&gt;datetime&lt;/a&gt; - replacement for &lt;a href="https://momentjs.com/"&gt;moment&lt;/a&gt; or &lt;a href="https://github.com/iamkun/dayjs"&gt;day.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/encoding"&gt;encoding&lt;/a&gt; - replacement for hand-picked yaml, toml, and other parsers&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/log"&gt;log&lt;/a&gt; and &lt;a href="https://deno.land/std@0.74.0/fmt/colors.ts"&gt;colors&lt;/a&gt; - replacement for &lt;a href="https://github.com/chalk/chalk"&gt;chalk&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/testing"&gt;testing&lt;/a&gt; - replacement for &lt;a href="https://jestjs.io/"&gt;Jest&lt;/a&gt; and &lt;a href="https://benchmarkjs.com/"&gt;benchmark.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/uuid"&gt;uuid&lt;/a&gt; - replacement for &lt;a href="https://www.npmjs.com/package/uuid"&gt;uuid&lt;/a&gt; (the npm package)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When I say "replacement" I don't mean they perform the same thing, but you might not need the entire 3rd party library when you can instead use Deno's versions.&lt;/p&gt;

&lt;p&gt;And then of course you've got your standard filesystem utilities&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/path"&gt;path&lt;/a&gt; - like Node's path&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/fs"&gt;fs&lt;/a&gt; - like Node's fs&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/hash"&gt;hash&lt;/a&gt; - like Node's Crypto library&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/std@0.74.0/http"&gt;http&lt;/a&gt; - like Node's http&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and so on.&lt;/p&gt;

&lt;p&gt;A recurring theme in Deno is going to be removing the need for 3rd party tooling, a popular complaint of the modern JS ecosystem. I think this is a much nicer benefit than people give it credit for.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript
&lt;/h2&gt;

&lt;p&gt;I use TypeScript for just all my JavaScript projects these days. It's more about type completion and IDE intellisense than anything else. Refactoring code is much much easier and I don't have to keep tabbing between documentation and my code editor.&lt;/p&gt;

&lt;p&gt;Deno includes TS compilation out of the box. It claims to be a runtime for TypeScript, but it's more like a compiler with some Deno integration. You can import a TypeScript file directly, it's rather quick at compiling, and it doesn't produce any JavaScript files as output, as it's unnecessary. &lt;/p&gt;

&lt;p&gt;Not needing to set up your whole project with ts-node is a big win for people upset with boilerplate and configuration.&lt;/p&gt;

&lt;p&gt;It does feel like an unusual choice though, since TypeScript still feels "unofficial". It feels like as much of a necessity as something like Flow. I much prefer TypeScript and TypeScript does see much more use these days, but I do understand why some might see this as a bit controversial.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deno's API
&lt;/h2&gt;

&lt;p&gt;This is not the same as its standard library as these don't need to be imported and are generally considered stable (more on that later). Here are 2 fantastic ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData"&gt;FormData&lt;/a&gt; - a web API for sending forms instead of JSON-encoded data

&lt;ul&gt;
&lt;li&gt;Required for Discord Bots when uploading files, usually implemented with third party libraries in Node&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API"&gt;fetch&lt;/a&gt; - a web API for sending server requests.

&lt;ul&gt;
&lt;li&gt;Node requires 3rd party libraries. There are several to choose from with different strengths.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've done a fair amount of web testing and scraping with Deno. Having these 2 built in has been so much nicer than Node.js where the implementations are up to the library creators and may not follow how the web APIs work.&lt;/p&gt;

&lt;p&gt;Deno also defaults to promise-based operations instead of callbacks. In Node you will often need to &lt;em&gt;&lt;a href="https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original"&gt;promisify&lt;/a&gt;&lt;/em&gt; libraries or APIs in order to not slip into callback hell. With Deno, &lt;em&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols"&gt;Iterables&lt;/a&gt;&lt;/em&gt; and promises are defaults, so there's no need for glue code anymore!&lt;/p&gt;

&lt;h1&gt;
  
  
  The Good
&lt;/h1&gt;

&lt;p&gt;Those are my favorites. Now onto the "good" - the things that are really nice to have, but not as important to me as the aforementioned materials.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deno's Multi-Purpose Binary
&lt;/h2&gt;

&lt;p&gt;Deno's binary doesn't just run code. It also provides the ability to install Deno projects, inspect a Deno project, bundle code, generate documentation, and format.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://deno.land/manual@v1.4.6/tools/script_installer"&gt;installer&lt;/a&gt; - install Deno projects as CLI tools, like &lt;code&gt;npm i -g&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/manual@v1.4.6/tools/formatter"&gt;formatter&lt;/a&gt; - format code like Prettier according to predefined rules&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/manual@v1.4.6/tools/bundler"&gt;bundler&lt;/a&gt; - collects all code into a single file for use, even inlines imports for use in web environments&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/manual/tools/documentation_generator"&gt;doc generator&lt;/a&gt; - emits documentation using JSDoc to stdout or JSON to be used with a documentation displayer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/manual@v1.4.6/tools/dependency_inspector"&gt;info&lt;/a&gt; - shows dependencies&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://deno.land/manual@v1.4.6/getting_started/command_line_interface#watch-mode"&gt;watcher&lt;/a&gt; - mentioned in passing, it is an argument that arguably replaces &lt;a href="https://www.npmjs.com/package/nodemon"&gt;nodemon&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A lot of these were again possible with third-party tools, but having an opinionated, built-in way to do all this is super useful. The doc generator could be better, but is much better than nothing for all the people creating Deno libraries.&lt;/p&gt;

&lt;p&gt;The formatter is opinionated, so it lets many Deno projects maintain a consistent style. There are some aspects to it that I would change if I could, but I'm sure others think similarly about parts I would hate to be changed, so it's a compromise.&lt;/p&gt;

&lt;p&gt;The installer really cements my opinion of Deno's use case which I will again get into later.&lt;/p&gt;

&lt;h2&gt;
  
  
  No Package.json
&lt;/h2&gt;

&lt;p&gt;This can also be seen as a negative, but it's again one of the usual complaints against Node. The package.json file is often unwieldy and hard to read for some. It includes metadata about the package, custom scripts, and dependencies split into different categories. It does a lot at once, so Deno just gets rid of it. &lt;/p&gt;

&lt;p&gt;There is no one file to view all the dependencies, but that's what &lt;code&gt;deno info&lt;/code&gt; is for. The less configuration a project has, often the easier it is to read, so that's a nice plus. With no package.json, package-lock.json, or node_modules/, the root directory is often a bit cleaner than most Node projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import Maps
&lt;/h2&gt;

&lt;p&gt;One of the "bad" parts of Deno is that imports are always URLs or paths, never referencing some locally installed package directory, like &lt;code&gt;node_modules&lt;/code&gt;. Deno caches imports, so this isn't extraordinarily problematic, but it does make imports a big ole mess.&lt;/p&gt;

&lt;p&gt;We've gotten rid of both the package.json and package.lock files, but to remedy this, people usually end up making somewhat of an &lt;code&gt;exports.ts&lt;/code&gt; file. This file imports everything from URLs and then re-exports it for the rest of the package to use. This feels like yet another package.json, so Deno also includes import maps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://deno.land/manual@v1.4.6/linking_to_external_code/import_maps"&gt;Import maps&lt;/a&gt; let you alias imports and are something seen usually only with build tools like &lt;a href="https://rollupjs.org/guide/en/"&gt;Rollup&lt;/a&gt; and &lt;a href="https://webpack.js.org/"&gt;Webpack&lt;/a&gt;. So now instead of looking at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;readText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://packages.example.org/deno/cool-coder55/CoolLib/src/utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can instead have our imports looking like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;readText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;CoolLib/src/utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I've taken advantage of this a lot. Sometimes URLs are also versioned, so this allows us to update the version of a library by changing it in one place instead of every URL in our project one-by-one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;It might seem a bit weird to list this one last, but it's not something I think is as effective as it seems.&lt;/p&gt;

&lt;p&gt;Deno forces users to also list the &lt;a href="https://deno.land/manual@v1.4.6/getting_started/permissions"&gt;permissions&lt;/a&gt; they grant a program when installing projects or running files. This can be things like network ability, write access, read access, and environment variable access. &lt;/p&gt;

&lt;p&gt;This is usually one of the first things about Deno mentioned and I do think it makes sense as a default. It's sort of like immutability as a default in a language, you'd rather choose times when things should have access then try to restrict things after. I just don't think it has quite the effect that it feels it would in practice.&lt;/p&gt;

&lt;p&gt;The OSS scene is usually vetted for malicious code, so people are unlikely to check exactly why a program requires certain permissions. In fact, I often see people run files with &lt;code&gt;-A&lt;/code&gt; which automatically grants all permissions, rendering this precaution null and void. However, I do see cases where this is useful.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Bad
&lt;/h1&gt;

&lt;p&gt;With all the good over, we can now get into the frustrations. This section is not as large as the previous 2 combined, but it arguably has greater weight when deciding whether or not to adapt Deno for your projects. You may have been able to pick out some of this section from how I phrased things in earlier sections. &lt;/p&gt;

&lt;h2&gt;
  
  
  Immaturity
&lt;/h2&gt;

&lt;p&gt;What's fairly obvious is Deno is new. like &lt;strong&gt;really&lt;/strong&gt; new. v1.0.0 was released in May of this year (2020) and it still feels far from 1.0.0 when looked at as a whole. &lt;/p&gt;

&lt;p&gt;Deno still has &lt;a href="https://github.com/denoland/deno/issues/2295"&gt;no Arm32 builds&lt;/a&gt; which means that hosting scripts on a Raspberry pi Zero, 1, or 2 is not yet possible. I unfortunately produced a Deno Discord bot using &lt;a href="https://github.com/Skillz4Killz/Discordeno"&gt;Discordeno&lt;/a&gt; before finding this out and I have since rented a VPS. &lt;/p&gt;

&lt;p&gt;Deno has not had &lt;a href="https://en.wikipedia.org/wiki/International_Components_for_Unicode"&gt;ICU&lt;/a&gt; support for a while, which means all JavaScript unicode-aware functions and properties will not work. This includes the &lt;code&gt;u&lt;/code&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp"&gt;RegExp&lt;/a&gt; flag and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize"&gt;String.prototype.normalize()&lt;/a&gt;. It was initially rejected due to the proportionally massive bump in file size this would force, but &lt;a href="https://github.com/denoland/deno/issues/1968"&gt;recent discussion&lt;/a&gt; has shown that they're making progress with its integration.&lt;/p&gt;

&lt;p&gt;There is clearly a problem with npm interop. There has been some recent work towards that goal, but it's nowhere near ready. There are ways to import web-libraries or node libraries that don't use any Node APIs, but if your png-to-jpeg Node library even makes a single call to Node's API, that package isn't getting in your Deno project without a repository fork.&lt;/p&gt;

&lt;p&gt;There are still a few web APIs that Deno lacks. Node has some third party libraries to fill in the gaps, but these cannot be imported by Deno, so we're stuck without any option in that area. Sometimes the problem is even more fundamental than it just using Node APIs, like with &lt;a href="https://www.npmjs.com/package/canvas"&gt;node-canvas&lt;/a&gt; using Cairo. I am watching &lt;a href="https://github.com/Automattic/node-canvas/issues/1653"&gt;this issue&lt;/a&gt; at the moment, though.&lt;/p&gt;

&lt;p&gt;I don't know of any build tooling, so if you have a particular feature you'd like to add onto JavaScript, like &lt;a href="https://www.npmjs.com/package/import-glob"&gt;glob imports&lt;/a&gt;, good luck. This is theoretically possible to implement, but I've yet to see it in practice and I think many users of Deno would be against it philosophically.&lt;/p&gt;

&lt;p&gt;Deno has some support in code editors and debugging environments, but because it's a small player and it piggybacks off of the work done for Node.js, its debugger in VS Code &lt;strong&gt;has&lt;/strong&gt; broke due to some update, which forced me to roll back my VS Code version.&lt;/p&gt;

&lt;p&gt;Additionally, I've found bugs in Deno itself. This isn't much for a library, but when it affects crucial things like text rendering in console and leads to non-actionable error states, it surely presents a hurdle for anyone with less experience who wouldn't know where to turn.&lt;/p&gt;

&lt;p&gt;In general, I don't think I would have faired so well if I didn't have years of experience with other frustrating dev environments and the know-how of who and where to ask for help.&lt;/p&gt;

&lt;h2&gt;
  
  
  Breaking Changes
&lt;/h2&gt;

&lt;p&gt;Oh, and on the topic of it not feeling like 1.0.0? The standard library seems to be far from 1.0.0 these days. &lt;/p&gt;

&lt;p&gt;The standard library of course being the thing containing many very important utility functions, like basic file reading and parsing. Really interesting new libraries get added often and this means the entire library's stability is held back by new content. Since, according to &lt;a href="https://semver.org/#spec-item-4"&gt;the semver spec&lt;/a&gt;, semantic versioning doesn't need to be respected before 1.0.0, the entire standard library is unstable. Since most Deno scripts use the standard library, you cannot guarantee that you're able to run an older Deno script without rolling back your Deno version. The version of Deno isn't listed anywhere in a project, so you just have to guess.&lt;/p&gt;

&lt;p&gt;A lot of very important features are locked behind an &lt;code&gt;--unstable&lt;/code&gt; flag. With Deno, unlike some other languages/projects, this often means breaking changes are more likely than not. An awful lot is still behind stable, so it's rare to find a project that doesn't require it if it ever interacts with the file system.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;--unstable&lt;/code&gt; also doesn't let you opt into specific features. Recently, Deno forced projects to use &lt;code&gt;import type&lt;/code&gt; when importing types or your code would not run. This also affects libraries you import, so you cannot use modern Deno features anymore with older libraries. This requirement is theoretically going to be pushed into stable Deno, breaking its stability (unless they push the version to 2.0.0 by then). &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;tsConfig.json&lt;/code&gt; &lt;strong&gt;can&lt;/strong&gt; be edited, but most features cannot. Once you edit one, you must provide the defaults for everything else as well. Some features cannot be edited at all and this aspect wasn't extraordinarily clear, making the breaking change a very frustrating experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Lack of Scripts
&lt;/h2&gt;

&lt;p&gt;With the removal of &lt;code&gt;package.json&lt;/code&gt;, we can no longer bake a bunch of custom scripts into the project with short aliases. With Deno, the command to run a program can be rather long. Assuming the program has yet to be installed globally, you might be using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; deno run &lt;span class="nt"&gt;--allow-net&lt;/span&gt; &lt;span class="nt"&gt;--allow-read&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr &lt;span class="nt"&gt;--allow-write&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr mod.ts &lt;span class="nt"&gt;-q&lt;/span&gt; Stephen Fry &lt;span class="nt"&gt;-n&lt;/span&gt; funny &lt;span class="nt"&gt;-r&lt;/span&gt; 10 &lt;span class="nt"&gt;-p&lt;/span&gt; 10 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And yes, this is very similar to a script from a project of mine. Everything after &lt;code&gt;mod.ts&lt;/code&gt; is from my own project and so mostly my own doing. Luckily I can just press &lt;code&gt;UP&lt;/code&gt; on my keyboard to re-execute it, but this makes managing multiple scripts a bit messy.&lt;/p&gt;

&lt;p&gt;Some projects recommend including some sort of &lt;code&gt;run.sh&lt;/code&gt; file when the same commands need to be run again fairly often. This ends up defeating the benefit of a cleaner root directory, but it does provide a simplification over &lt;code&gt;package.json&lt;/code&gt; since the file only does one thing. This does require another file per script. We &lt;em&gt;could&lt;/em&gt; probably add a &lt;code&gt;scripts.toml&lt;/code&gt; file and then add a make a &lt;a href="https://www.nushell.sh/"&gt;nushell&lt;/a&gt; or bash script to read it and execute the desired script, but these are again things not native to Deno.&lt;/p&gt;

&lt;p&gt;Admittedly, the most common use cases for differing scripts are testing, transpiling TS, bundling, and file watchers. Deno includes all of those natively. One might use a bundler for more than what Deno provides, however, such as supporting custom JS features through a second stage of traspilation.  &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion - The Use Case
&lt;/h1&gt;

&lt;p&gt;Deno is not production ready. It has passed 1.0.0, but it has not "passed 1.0". By "production ready" I mean don't build something if you're hoping for stability.&lt;/p&gt;

&lt;p&gt;I'm a big fan of "new software" in general. Maybe that's a naive quality. I find that newer software has the advantage of creating much more sensible defaults based on past experiences. It is able to learn from other frustrations and break convention. Languages like Rust and Nim and now Deno show this well. &lt;/p&gt;

&lt;p&gt;Even Deno &lt;em&gt;libraries&lt;/em&gt; are often "better" versions of Node libraries that had some clear faults. It often takes some getting used to, but you end up with a better product (either in DX or performance).&lt;/p&gt;

&lt;p&gt;Deno's main use case seems to be with small scripts. As long as these scripts are bundled using &lt;code&gt;deno bundle&lt;/code&gt; and a Deno compatibility version is listed, it should be fine. It will be rather frustrating to switch Deno versions each time you want to run a script, however.&lt;/p&gt;

&lt;p&gt;I don't live in the CLI myself, but due to Deno's match with Web APIs, I've found web scraping and http requests to be much nicer with Deno. There should be some advancement on that end as well if Deno ever decides to add &lt;a href="https://github.com/b-fuze/deno-dom"&gt;DOMParser&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm going to continue using Deno for basic scripts and web scraping. I've worked through enough bugs and frustrations that I think I'll be able to avoid them to some extent. It's much easier to set up a Deno project than a Node.js one which makes prototyping much nicer. I think this is a use case most could get behind.&lt;/p&gt;

</description>
      <category>deno</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Decoding UTF-8</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Wed, 09 Sep 2020 14:41:44 +0000</pubDate>
      <link>https://dev.to/emnudge/decoding-utf-8-3947</link>
      <guid>https://dev.to/emnudge/decoding-utf-8-3947</guid>
      <description>&lt;p&gt;I'm a JavaScript guy, so this is a bit of a weird article. I recently went through a month's worth of research into unicode for an &lt;a href="https://dev.to/emnudge/adventures-in-horrible-no-good-very-bad-variable-names-20ii"&gt;article&lt;/a&gt; and then subsequent &lt;a href="https://www.youtube.com/watch?v=vHkM6RwA7Wk" rel="noopener noreferrer"&gt;video&lt;/a&gt; on variable names. JavaScript uses UTF-16 and I put some more specific info into the &lt;a href="https://www.youtube.com/watch?v=ZQRAMHiVEzs" rel="noopener noreferrer"&gt;extra video&lt;/a&gt;, rather than the main video.&lt;/p&gt;

&lt;p&gt;I'd advise watching it if you're curious. I was recently asked about UTF-8 by another JavaScript developer and so I decided to look into it. Resources online are scarce or not friendly enough that I was asked to turn my personal explanation into an article for future reference.&lt;/p&gt;

&lt;p&gt;First off, why UTF-8?&lt;/p&gt;

&lt;h1&gt;
  
  
  Encoding Unicode
&lt;/h1&gt;

&lt;p&gt;Every unicode encoding is tasked with a similar problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How do we represent all 1.1M possible code points?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The actual number is &lt;code&gt;1_111_998&lt;/code&gt;. In binary this takes up 21 bits. That means it's possible to have a single character that &lt;strong&gt;must&lt;/strong&gt; require us to use &lt;code&gt;21&lt;/code&gt;  bits at a minimum to encode.&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%2Fynl1asdzclxldylzelhy.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%2Fynl1asdzclxldylzelhy.png" alt="Unicode bits"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We stick to powers of 2 for binary encoding, so our first thought might be exactly what &lt;a href="https://en.wikipedia.org/wiki/UTF-32" rel="noopener noreferrer"&gt;UTF-32&lt;/a&gt; is today. Let's use 32 bits!&lt;/p&gt;

&lt;p&gt;This works, but is very inefficient. If we approach a character that requires 21 bits, we'll need to use 4 bytes (32 bits) anyway, but most characters do not have a codepoint that large. This means we are wasting  the first 11 bits of every codepoint, at a &lt;strong&gt;minimum&lt;/strong&gt;. In fact, this article only uses 3 characters larger than 122 (the 3 example characters later on in the article)! That's (for the most part) only 7 bits per character!&lt;/p&gt;

&lt;p&gt;In comes &lt;a href="https://en.wikipedia.org/wiki/UTF-16" rel="noopener noreferrer"&gt;UTF-16&lt;/a&gt; with a clever trick.&lt;/p&gt;

&lt;h2&gt;
  
  
  UTF-16
&lt;/h2&gt;

&lt;p&gt;It recognizes that characters with codepoints that require more than 16 bits are even more rare! 16 bits gives us roughly 65k possible codepoints. What we do is reserve 2 separate ranges of 1024 characters out of our initial 65k codepoints available. These are used for "surrogate pairs" (more info my &lt;a href="https://www.youtube.com/watch?v=ZQRAMHiVEzs" rel="noopener noreferrer"&gt;unicode extras video&lt;/a&gt;). Using a bit of math we find that if we combine them, we're able to get 20 more bits (enabling &lt;code&gt;1_048_576&lt;/code&gt; more characters).&lt;/p&gt;

&lt;p&gt;If we go by character by character, as computers usually do, we're able to tell whether the codepoint we are looking at is a lone one or a surrogate pair just by checking what range it is in! &lt;/p&gt;

&lt;p&gt;This way we can shave off 16-bits for most characters! The surrogate pair ranges are purposely empty anyway, so we're not kicking any characters out.&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%2Fuploads%2Farticles%2Fy4e44a1t4kjvrce87ile.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%2Fuploads%2Farticles%2Fy4e44a1t4kjvrce87ile.png" alt="Unicode Block Infographic"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While JavaScript uses UTF-16, HTML traditionally uses UTF-8. Only 8 bits? It looks like we barely got by with 16 bits! Are we going to reserve another few ranges? How? Out of 256 possible codepoints, which ranges do we reserve?! &lt;/p&gt;

&lt;p&gt;We could use multiple bytes for larger codepoints, but how would we ever know if we were currently looking at a lone character or one that is meant to be read together with others? UTF-16 and UTF-32 gives us the guarantee that we'll be able to start from anywhere in a file and, provided we know our index, we can regain our footing.&lt;/p&gt;

&lt;h2&gt;
  
  
  UTF-8
&lt;/h2&gt;

&lt;p&gt;And now the point of the article. UTF-8 takes a different approach. Instead of reserving a specific range, each starting byte will tell us how many &lt;strong&gt;more&lt;/strong&gt; bytes to expect. The answer to this can be either 0, 1, 2, or 3, since UTF-8 characters can be composed of anywhere from 1 to 4 characters.&lt;/p&gt;

&lt;p&gt;Our base case is 0. &lt;/p&gt;

&lt;p&gt;If we're given a byte that begins with a &lt;code&gt;0&lt;/code&gt;, then this is the only codepoint required to parse this into a character. Using the codepoint of 103 as an example (the character &lt;code&gt;g&lt;/code&gt;),  its UTF-8 encoding would be &lt;code&gt;01100111&lt;/code&gt;. Notice the leading &lt;code&gt;0&lt;/code&gt;. We can express this codepoint with 7 bits, so we use the leading bit to tell whomever is asking that this is the only number in this sequence. Only one byte!&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%2Fxa87dekrksy2w5ucl4cv.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%2Fxa87dekrksy2w5ucl4cv.png" alt="7 bit characters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This works fine up until codepoints over 127. In such a case we are forced to use 2 bytes. &lt;/p&gt;

&lt;p&gt;We need to signal this somehow. UTF-8 tells us to start the first byte with &lt;code&gt;110&lt;/code&gt;. The second byte must start with &lt;code&gt;10&lt;/code&gt;. Since each byte is 8 bits, we're left with  &lt;code&gt;(8 - 3) + (8 - 2) =&lt;/code&gt; 11 total bits! This allows us to express codepoints in the range 128-2047.&lt;/p&gt;

&lt;p&gt;Therefore the British Pound (&lt;code&gt;£&lt;/code&gt;), with a codepoint of 163, requires 2 bytes. Its direct binary representation is &lt;code&gt;10100011&lt;/code&gt;. Expanding it to the full 11 bits turns it to &lt;code&gt;00010100011&lt;/code&gt;. Combining the required &lt;code&gt;110&lt;/code&gt; with the first 5 bits gives us &lt;code&gt;11000010&lt;/code&gt; for our first bit. Our second bit then combines &lt;code&gt;10&lt;/code&gt; with our remaining 6 bits (&lt;code&gt;100011&lt;/code&gt;) gives us &lt;code&gt;10100011&lt;/code&gt;.&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%2Fej0z66rbeqxmir5dgjdq.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%2Fej0z66rbeqxmir5dgjdq.png" alt="11 bit characters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But again, this only covers the first 2047 characters. For larger codepoints (up until 65,536) we need 3 bytes. &lt;/p&gt;

&lt;p&gt;This time we use &lt;code&gt;1110&lt;/code&gt; (notice an extra &lt;code&gt;1&lt;/code&gt;) at the start and follow it up by 2 numbers which both start with &lt;code&gt;10&lt;/code&gt;. This is useful for codepoints such as &lt;code&gt;￫&lt;/code&gt; which have a codepoint of &lt;code&gt;65_515&lt;/code&gt;. Since this time it leaves us with &lt;code&gt;(8 - 4) + 2(8 - 2) =&lt;/code&gt; 16 bits to express 63,488 more characters!&lt;/p&gt;

&lt;p&gt;And finally we get to the remaining characters. &lt;/p&gt;

&lt;p&gt;For characters such as 😀, with a codepoint of &lt;code&gt;128_512&lt;/code&gt;, we can use a leading &lt;code&gt;11110&lt;/code&gt; (another &lt;code&gt;1&lt;/code&gt;) to signal that this is a part of a 4 byte codepoint. The next 3 characters again start with &lt;code&gt;10&lt;/code&gt;. Applying our basic math expression, we find this leaves us with &lt;code&gt;(8 - 5) + 3(8 - 2) =&lt;/code&gt; 21 bits! Exactly enough to express all unicode codepoints!&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%2F135p2qbze2d9eyw7c5l7.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%2F135p2qbze2d9eyw7c5l7.png" alt="16 and 21 bit characters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Algorithm
&lt;/h2&gt;

&lt;p&gt;Now that we've gone through the explanation, let's make it concise with some steps. Let's say  we're placed at a random byte in a file which we know to be UTF-8 encoded.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Does this byte begin with a &lt;code&gt;0&lt;/code&gt;? If so this can be parsed by itself and we can move on to the next byte.&lt;/li&gt;
&lt;li&gt;Does this byte begin with &lt;code&gt;10&lt;/code&gt;? Whoops! If so, we're in the middle of a character! We need to move forward until this is no longer the case or move backwards to find out what sort of character we were trying to parse.&lt;/li&gt;
&lt;li&gt;Does this byte begin with 2-4 &lt;code&gt;1&lt;/code&gt;s followed up by a &lt;code&gt;0&lt;/code&gt;? If so, provided &lt;code&gt;n&lt;/code&gt; refers to the number of &lt;code&gt;1&lt;/code&gt;s, we've approached an &lt;code&gt;n&lt;/code&gt;-byte codepoint and should parse the next &lt;code&gt;n - 1&lt;/code&gt; bytes and this one as a single codepoint.&lt;/li&gt;
&lt;li&gt;Does this byte begin with 5 or more &lt;code&gt;1&lt;/code&gt;s? This is invalid UTF-8! Well, maybe. Perhaps in the future we have somehow expanded to ~69 Billion codepoints. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Code
&lt;/h2&gt;

&lt;p&gt;Because we're in binary-land, we also have quite a few operators at our disposal to make things more efficient - &lt;a href="https://developer.mozilla.org/tr/docs/Web/JavaScript/Reference/Operat%C3%B6rler/Bitwise_Operators" rel="noopener noreferrer"&gt;bitwise operators&lt;/a&gt;. They're a bit unintuitive at first, so I suggest going through them at first to fully understand &lt;em&gt;what&lt;/em&gt; they do before seeing &lt;em&gt;how&lt;/em&gt; they're used.&lt;/p&gt;

&lt;p&gt;I've placed the code for my UTF-8 encoder/decoder into a Svelte REPL over here: &lt;a href="https://svelte.dev/repl/9d89e50badbd458599fc62cde67fc9b3?version=3.24.1" rel="noopener noreferrer"&gt;https://svelte.dev/repl/9d89e50badbd458599fc62cde67fc9b3?version=3.24.1&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I won't be going over the majority of the code, since it'd be a bit too much for this article (and a bit too boring, frankly), so let's just clarify 2 common operations that use bitwise operators in the code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Retrieving Part of a Binary

&lt;ul&gt;
&lt;li&gt;To isolate a binary, we create another binary with the bits we want to preserve and use the &lt;code&gt;&amp;amp;&lt;/code&gt; operator - make every bit you want to keep a &lt;code&gt;1&lt;/code&gt;. If it starts in the middle, we can use the &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; operator to move it back to the start.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0b1111 &amp;amp; myBinary&lt;/code&gt; = isolate the first 4 bits&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;(0b111100 &amp;amp; myBinary) &amp;gt;&amp;gt; 2&lt;/code&gt; = isolate the first 4 bits after the first 2 bits&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Adding on Bits to a Binary

&lt;ul&gt;
&lt;li&gt;We cannot add on without knowing the binary length. If we do, just create a binary with &lt;code&gt;n&lt;/code&gt; digits + however many the binary is and use the &lt;code&gt;|&lt;/code&gt; operator. Make the rest of the bits (first &lt;code&gt;n&lt;/code&gt; digits) all &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0b10000 | myBinary&lt;/code&gt; = if binary is 3 digits long, adds on &lt;code&gt;10&lt;/code&gt; to the end.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;0b10000000 | ((myBinary &amp;gt;&amp;gt; 6) &amp;amp; 0b111111)&lt;/code&gt; = take the first 6 bits and add on &lt;code&gt;10&lt;/code&gt; to the end.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Conclusion - Efficiency
&lt;/h1&gt;

&lt;p&gt;From the looks of it, it seems like UTF-8 is the most efficient encoding so far. However, there are clearly some edge cases where it would be much less efficient than something like UTF-16.&lt;/p&gt;

&lt;p&gt;As a closing, here are 2 quick tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On something like Herman Melville's Moby Dick in English, UTF-16 increases the file size just about twofold, from &lt;code&gt;1.19MB&lt;/code&gt; to &lt;code&gt;2.39MB&lt;/code&gt; as the majority of its characters (from the text file I found) would be within the first 127 codepoints. That's one byte per character in UTF-8 and 2 in UTF-16). UTF-32 would no doubt have doubled it yet again.&lt;/li&gt;
&lt;li&gt;On Dan Abramov's &lt;a href="https://overreacted.io/my-decade-in-review/" rel="noopener noreferrer"&gt;My Decade In Review&lt;/a&gt; in Simplified Chinese, UTF-16 is slightly smaller than the UTF-8 variant (28.8kb vs 36kb). Many of the codepoints are in the ~25k range. This would be 3 bytes in UTF-8 and only 2 in UTF-16 - a roughly 1.5x increase. The markdown file also includes many links and single byte UTF-8 characters, which is why it isn't entirely &lt;code&gt;1.5x&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without looking anything up, we can assert that UTF-8 would be less efficient than UTF-16 for characters with codepoints between 2048-65534. This would favor UTF-16 when such codepoints dominate the medium, like a book rather than a blogpost, where the benefit is only marginal due to the quantity of single-byte characters that UTF-16 forces to be 2 bytes.&lt;/p&gt;

&lt;p&gt;UTF-16 would almost always be more space-efficient than UTF-32 unless the Unicode standard opened up codepoints that could be expressed with 22-32 bits. In which case such codepoints would be better expressed with UTF-32.&lt;/p&gt;

&lt;p&gt;For most purposes, particularly code in just about any programming language, UTF-8 is more efficient. &lt;/p&gt;

&lt;p&gt;In regards to computational efficiency, the efficiency order would go in reverse - UTF-32, UTF-16, and then UTF-8. &lt;/p&gt;

&lt;p&gt;Lossless compression formats such as &lt;code&gt;.zip&lt;/code&gt; and &lt;code&gt;.72&lt;/code&gt; would also likely make the size differences much thinner (or perhaps even reverse the current order). Specially tailored compression formats even more so. While these encoders work on character to character, other compression formats may be able to work on text blobs as a whole.&lt;/p&gt;

&lt;p&gt;Critique? Let me know in the comments!&lt;/p&gt;

</description>
      <category>unicode</category>
      <category>javascript</category>
      <category>utf8</category>
      <category>utf16</category>
    </item>
    <item>
      <title>From Scratch - Reactive Values</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Mon, 10 Aug 2020 17:58:08 +0000</pubDate>
      <link>https://dev.to/emnudge/from-scratch-reactive-values-c9h</link>
      <guid>https://dev.to/emnudge/from-scratch-reactive-values-c9h</guid>
      <description>&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: This was originally a script for a video. As it takes months at times to release a video, I've decided to turn what I have into an article as well.&lt;/p&gt;

&lt;p&gt;I'm a fairly big proponent of the idea that certain programming topics are best taught by discussing the low level fundamentals rather than the high level API. In the same way that &lt;a href="https://egghead.io/courses/getting-started-with-redux"&gt;Dan Abramov teaches Redux&lt;/a&gt; or &lt;a href="https://www.youtube.com/channel/UC56l7uZA209tlPTVOJiJ8Tw"&gt;Francis Stokes teaches just about anything&lt;/a&gt;.&lt;br&gt;
In this article we're going to discuss a fairly hip JavaScript topic: Reactive Data Structures. Let's first get into a use case.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;For the most basic of use cases, let's try to share data between modules. Perhaps we're creating a game and we want our score to be able to be changed via multiple different modules containing their own functions. &lt;/p&gt;

&lt;p&gt;For this purpose we usually create somewhat of a function hierarchy (see &lt;a href="https://reactjs.org/docs/thinking-in-react.html"&gt;React's Data Flow&lt;/a&gt;), but this may require us to change our main function when we want a change in a smaller function. It also leads to highly nested code with data being passed through multiple levels for simple updates (known in React as &lt;a href="https://kentcdodds.com/blog/prop-drilling"&gt;Prop Drilling&lt;/a&gt;). So we're not going to go with that method. &lt;/p&gt;

&lt;p&gt;Frameworks like &lt;a href="https://github.com/ryansolid/solid"&gt;Solid.js&lt;/a&gt; and &lt;a href="https://svelte.dev/"&gt;Svelte.js&lt;/a&gt; solve this problem using Reactive Data Structures, often called &lt;a href="https://svelte.dev/tutorial/writable-stores"&gt;&lt;code&gt;Store&lt;/code&gt;&lt;/a&gt;s or &lt;a href="https://github.com/ryansolid/solid/blob/master/documentation/reactivity.md#signals"&gt;&lt;code&gt;Signal&lt;/code&gt;&lt;/a&gt;s. Other frameworks may have slightly differing approaches, like React's &lt;a href="https://reactjs.org/docs/context.html"&gt;Context&lt;/a&gt; and Vue's &lt;a href="https://vuex.vuejs.org/"&gt;Vuex&lt;/a&gt;. We're going to implement the Solid/Svelte approach without using the framework.&lt;/p&gt;

&lt;p&gt;Let's set up our code. We'll store all data, such as our score, in a file called &lt;code&gt;data.js&lt;/code&gt;. Our main file, &lt;code&gt;index.js&lt;/code&gt;, will be responsible for taking the score and displaying it, as well as importing the &lt;code&gt;buttons.js&lt;/code&gt; file which contains the code for our buttons.&lt;/p&gt;

&lt;p&gt;We could just create another script tag instead of an import, but I prefer this method.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code below available at: &lt;a href="https://codesandbox.io/s/reactor-p1-nu3ik"&gt;https://codesandbox.io/s/reactor-p1-nu3ik&lt;/a&gt;&lt;/em&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="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nx"&gt;buttons&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- index.html --&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Reactor Example&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"index.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"score"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;0&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"score-increase"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Increase Score&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"score-decrease"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Decrease Score&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./buttons.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./data.js&lt;/span&gt;&lt;span class="dl"&gt;'&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;h1&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1.score&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`score: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;score&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our first instinct here is just to export a variable called score that points to a number.&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="c1"&gt;// data.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// buttons.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./data.js&lt;/span&gt;&lt;span class="dl"&gt;'&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;b1&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button.score-increase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="o"&gt;++&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;b2&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="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button.score-decrease&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;b2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're unfortunately going to run into a problem immediately. We cannot assign to any imported variables. They're defined as constant binding values when imported. Changing it to &lt;code&gt;let&lt;/code&gt; won't help either, as it will only be mutable to the module it's exported from. &lt;/p&gt;

&lt;p&gt;One option might be to use &lt;code&gt;export let&lt;/code&gt; and also export a &lt;code&gt;changeScore&lt;/code&gt; function which should have edit access. There's a simpler solution, however.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Objects
&lt;/h2&gt;

&lt;p&gt;As with all constant variables in JavaScript, we actually can change its properties if it's an object. Moving score to an object with a value property is an easy fix there.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code below available at: &lt;a href="https://codesandbox.io/s/reactor-p2-5obug"&gt;https://codesandbox.io/s/reactor-p2-5obug&lt;/a&gt;&lt;/em&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="c1"&gt;// data.js&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;value&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// buttons.js&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nx"&gt;b1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nx"&gt;b2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nx"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`score: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;score&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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this actually works. Our value is changed and the changes carries over from module to module. We're not seeing any change visually, however. When we click our buttons, the &lt;code&gt;h1&lt;/code&gt; does not update.&lt;/p&gt;

&lt;p&gt;This is because our code in &lt;code&gt;index.js&lt;/code&gt; is only ran once. It has no idea when our data has changed. We can probably start an interval which sets our value ever few milliseconds, but this really isn't a viable option for everywhere that we end up using our score. &lt;/p&gt;

&lt;p&gt;A better alternative is to have our score tell everyone when its value changes. Like a newspaper, we can give people the option to subscribe and we'll notify them when we get a new issue... or value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Subscribers
&lt;/h2&gt;

&lt;p&gt;This requires us to know when we've been mutated. We usually use functions for this thing, but we can preserve using &lt;code&gt;.value&lt;/code&gt; by turning our object into a class and creating &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get"&gt;getters&lt;/a&gt; and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set"&gt;setters&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Note that, with the exception of Vue.js and a few others, this isn't often how reactivity libs work - we often just use functions for updating. For this article, I prefer the OOP method as it cuts down on some code complexity. We don't need a separate &lt;code&gt;read&lt;/code&gt;, &lt;code&gt;set&lt;/code&gt;, and &lt;code&gt;update&lt;/code&gt; method (&lt;code&gt;update&lt;/code&gt; takes a function, whereas &lt;code&gt;set&lt;/code&gt; only takes a value). I advise you to look up getters and setters in JS, however, if you're unfamiliar.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code below available at: &lt;a href="https://codesandbox.io/s/reactor-p3-e8dxg"&gt;https://codesandbox.io/s/reactor-p3-e8dxg&lt;/a&gt;&lt;/em&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="c1"&gt;// reactor.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&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="c1"&gt;// private value for where it's really stored&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;_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="c1"&gt;// private list of functions to be notified&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;_subscribers&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="c1"&gt;// return value when requested&lt;/span&gt;
  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;value&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="k"&gt;this&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;// set value and then notify everyone&lt;/span&gt;
  &lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;)&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;_val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newVal&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;const&lt;/span&gt; &lt;span class="nx"&gt;subscribeFunc&lt;/span&gt; &lt;span class="k"&gt;of&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;_subscribers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;subscribeFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newVal&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;// add function to subscriber list and immediately invoke&lt;/span&gt;
  &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;_subscribers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;func&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;_val&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;One way that we differ from a newspaper is that subscribers get a value instantly upon subscription. This lets our score counter work without having to set it an additional time right before subscribing, but it's also important to keep this in mind for a feature we're going to add later.&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="c1"&gt;// data.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reactor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./reactor.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&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;h1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;textContent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`score: &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="s2"&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;At this point we've already created a reactive data structure. The fact that this reacts to changes and updates its subscribers is the reactivity we've been looking for. We can have one reactive value update another reactive value and create chains of reactivity.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;halfScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;halfScore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One thing we can't really do as easily though is have one value change in response to any of multiple values changing. What if we want to generate a high score out of multiple reactive scores? We might do something 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="c1"&gt;// example.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reactor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reactor.js&lt;/span&gt;&lt;span class="dl"&gt;'&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;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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;highScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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;// finds highest reactive score and changes highScore to it&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setHighScore&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;// we use this for scores as well, so check if it's a number&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;highestNum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&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="mi"&gt;0&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;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;scores&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;highestNum&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;highestNum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;score&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="nx"&gt;highScore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;highestNum&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// adds new score and makes it reactive when changed&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;addScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setHighScore&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// we cannot use .push() - we need to use = for it to react&lt;/span&gt;
    &lt;span class="nx"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;scores&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;score&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nf"&gt;addScore&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="nf"&gt;addScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;addScore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks a bit messier than I'd like it to. We're forced to have our &lt;code&gt;addScore&lt;/code&gt; also subscribe each score individually. Since our &lt;code&gt;subscribe&lt;/code&gt; function is called immediately, we're also updating the &lt;code&gt;highScore&lt;/code&gt; when add add a new one, but if we added one any other way, it wouldn't update the high score.&lt;/p&gt;

&lt;h2&gt;
  
  
  Computed Values
&lt;/h2&gt;

&lt;p&gt;There's a cleaner way - computed values. At the cost of more complex library code, we get a cleaner user experience. Here's what a computed version of that code might look like.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reactor.js&lt;/span&gt;&lt;span class="dl"&gt;'&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;scores&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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;highScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;highestVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;const&lt;/span&gt; &lt;span class="nx"&gt;score&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;scores&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;score&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;highestVal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;highestVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;score&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;highestVal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;highsScore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;high score: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// high score: 0&lt;/span&gt;

&lt;span class="nx"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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;// high score: 0&lt;/span&gt;

&lt;span class="nx"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;scores&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
&lt;span class="c1"&gt;// high score: 45&lt;/span&gt;

&lt;span class="nx"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;scores&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;&lt;span class="p"&gt;)];&lt;/span&gt;
&lt;span class="c1"&gt;// high score: 45&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;firstScore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;scores&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="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="nx"&gt;firstScore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;103&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// high score: 103&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm not sure if we're all looking at the same code here, but this looks like magic to me.&lt;/p&gt;

&lt;p&gt;Our high score will change whenever a new value is added or when any value inside of it changes its own value.&lt;/p&gt;

&lt;p&gt;...how?&lt;/p&gt;

&lt;p&gt;We're not subscribing to anything. How does the &lt;code&gt;computed&lt;/code&gt; function know about which variables are inside of it? We're not stringifying anything and we're not doing static analysis. We're using an array, so there aren't any unique variable names. Is this something specifically with arrays?&lt;/p&gt;

&lt;p&gt;Nope! Here's a sample with some other values:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reactor.js&lt;/span&gt;&lt;span class="dl"&gt;'&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;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;45&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;num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;92&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;unusedVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;34&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;num4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&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;num1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num2&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;num4&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;num4: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="c1"&gt;// num4: 137&lt;/span&gt;

&lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// num4: 100&lt;/span&gt;

&lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// num4: 10&lt;/span&gt;

&lt;span class="nx"&gt;unusedVal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// num4 is unchanged and doesn't console.log since we never used unusedVal for num4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A computed value is like a regular subscription, but it allows us to subscribe, dynamically, to multiple values. It knows exactly which reactive variables are inside it and only has them specifically subscribed.&lt;/p&gt;

&lt;p&gt;This seems impossible unless &lt;code&gt;computed&lt;/code&gt; and &lt;code&gt;Reactor&lt;/code&gt; are communicating in some way. They're separate, but they must share some sort of local state or else there's no way this is possible.&lt;/p&gt;

&lt;p&gt;And that's right on the mark. The trick to all of this working is the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We automatically run subscriptions once after subscribing.&lt;/li&gt;
&lt;li&gt;There is a single (non-exported, but top-level) variable in the same module as both &lt;code&gt;computed&lt;/code&gt; and &lt;code&gt;Reactor&lt;/code&gt; that may or may not have a value at any given time.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Trick
&lt;/h2&gt;

&lt;p&gt;So &lt;code&gt;computed&lt;/code&gt; is able to communicate with &lt;code&gt;Reactor&lt;/code&gt; by the following method:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Set our local variable (&lt;code&gt;computeFunc&lt;/code&gt;) to the function passed to &lt;code&gt;computed&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;Run the function passed to &lt;code&gt;computed&lt;/code&gt; once.&lt;/li&gt;
&lt;li&gt;Have &lt;code&gt;Reactor&lt;/code&gt; values automatically subscribe to &lt;code&gt;computeFunc&lt;/code&gt; when they're read from and &lt;code&gt;computeFunc&lt;/code&gt; is not empty.&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;computeFunc&lt;/code&gt; back to what it was before.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This way, we're able to communicate with all reactive values in the function without knowing specifically what they are, since it's the job of the reactive values themselves to check this variable.&lt;/p&gt;

&lt;p&gt;To reiterate, since this is perhaps the most complex part of this article - both &lt;code&gt;computed&lt;/code&gt; and &lt;code&gt;Reactor&lt;/code&gt; have &lt;code&gt;computeFunc&lt;/code&gt; in scope. &lt;code&gt;computeFunc&lt;/code&gt; is &lt;strong&gt;usually&lt;/strong&gt; empty. As JS, in this context, is single threaded, the only time it &lt;strong&gt;ever&lt;/strong&gt; contains a value is &lt;strong&gt;exactly&lt;/strong&gt; when &lt;code&gt;computed&lt;/code&gt; initially runs. This way we're ensuring that every &lt;code&gt;Reactor&lt;/code&gt; inside the function passed to &lt;code&gt;computed&lt;/code&gt; subscribes to this function. If we did not set &lt;code&gt;computeFunc&lt;/code&gt; back to what it was before (usually &lt;code&gt;undefined&lt;/code&gt;), then every reactive value would subscribe to it - even ones not related to any &lt;code&gt;computed&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We set it back to "what it was before" and not &lt;code&gt;undefined&lt;/code&gt; because &lt;code&gt;computed&lt;/code&gt; values can contain &lt;code&gt;computed&lt;/code&gt; values. This means we may be getting deep into some stack and since &lt;strong&gt;every&lt;/strong&gt; &lt;code&gt;computed&lt;/code&gt; uses the same variable, &lt;code&gt;computeFunc&lt;/code&gt;, we need to set it back to was before, as it may have not been &lt;code&gt;undefined&lt;/code&gt;, but just some other function. &lt;/p&gt;

&lt;p&gt;That was a lot of talk and perhaps it may be clearer in code. A computed value is just a regular &lt;code&gt;Reactor&lt;/code&gt;, so let's set that up first.&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="c1"&gt;// reactor.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// we can give it anything, since we're changing it momentarily&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reactor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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="c1"&gt;// run it immediately to get a new value&lt;/span&gt;
    &lt;span class="nx"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&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;reactor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This doesn't look like much yet. Let's add our local variable and change &lt;code&gt;Reactor&lt;/code&gt; to check for it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code below available at: &lt;a href="https://codesandbox.io/s/reactor-p4-1tcij?file=/reactor.js"&gt;https://codesandbox.io/s/reactor-p4-1tcij?file=/reactor.js&lt;/a&gt;&lt;/em&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="c1"&gt;// reactor.js&lt;/span&gt;

&lt;span class="c1"&gt;// initially undefined. We can set it to null instead. &lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;computeFunc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;reactor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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="c1"&gt;// THIS is the function we subscribe to, which updates the reactor&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&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;reactor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// set computeFunc to fn and store previous value for later&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prevVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computeFunc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;computeFunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nf"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// set computeFunc back to previous value&lt;/span&gt;
    &lt;span class="nx"&gt;computeFunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prevVal&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;reactor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;

    &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If it exists, we add it to the subscribers.&lt;/span&gt;
        &lt;span class="c1"&gt;// Do not call it, unlike a regular subscriber.&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;computeFunc&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;_subscribers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;computeFunc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;return&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;_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;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And now &lt;code&gt;computed&lt;/code&gt; works! We can create new reactive values from other ones. &lt;/p&gt;

&lt;p&gt;We're not quite done yet, however. We'll find that our array example does not work yet. This is  because our &lt;code&gt;computed&lt;/code&gt; function does not account for dynamically added values. &lt;/p&gt;

&lt;h2&gt;
  
  
  Accounting For Arrays &amp;amp; Cleanup
&lt;/h2&gt;

&lt;p&gt;We're only setting &lt;code&gt;computeFunc&lt;/code&gt; on the initial function creation, so only the &lt;code&gt;Reactor&lt;/code&gt;s that are inside the &lt;code&gt;computeFunc&lt;/code&gt; on initial creation will subscribe to &lt;code&gt;fn&lt;/code&gt;.  With our array example, we're adding reactive values even after &lt;code&gt;computed&lt;/code&gt; is initially called. We need to change &lt;code&gt;fn&lt;/code&gt; to account for that.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code below available at: &lt;a href="https://codesandbox.io/s/reactor-p5-cdx10?file=/reactor.js"&gt;https://codesandbox.io/s/reactor-p5-cdx10?file=/reactor.js&lt;/a&gt;&lt;/em&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;reactor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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="c1"&gt;// move the local variable assignment into the subcribed function&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;prevVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;computeFunc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;computeFunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="nx"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nx"&gt;computeFunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prevVal&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="nf"&gt;fn&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;reactor&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 problem with &lt;em&gt;this&lt;/em&gt; is that we're now going to run into an infinite loop. Whenever a reactive value in the &lt;code&gt;computed&lt;/code&gt; is changed, we loop through our subscribed functions and call them.&lt;/p&gt;

&lt;p&gt;Then the function we're subscribing to is setting &lt;code&gt;ComputeFunc&lt;/code&gt; and calling our &lt;code&gt;get value&lt;/code&gt; method. Doing that forces us to add a subscriber to ourself. We're adding a subscriber while looping through subscribers, so we always have another subscriber to loop over. Thus, an infinite loop.&lt;/p&gt;

&lt;p&gt;A quick solution is making sure we have no duplicates of any functions in our array. Move our array to a &lt;code&gt;new Set()&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Reactor&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&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="c1"&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;_subscribers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;value&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// change from .push() to .add()&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;computeFunc&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;_subscribers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;computeFunc&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;_subscribers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&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;At this point we may want to add some more cleanup code. Different reactive libs have different sort of safe guards and differing ways to do similar things. We may want to firstly add an &lt;code&gt;unsubscribe&lt;/code&gt; function, which is usually just returned from the &lt;code&gt;subscribe&lt;/code&gt; function.&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="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;_subscribers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nf"&gt;func&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;_val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="c1"&gt;// remove the subscriber&lt;/span&gt;
  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;_subscribers&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;func&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;Using &lt;code&gt;Set&lt;/code&gt; makes this process super clean.&lt;/p&gt;

&lt;p&gt;We also may want to add some infinite loop protection. That can be done by checking if the function we're in (&lt;code&gt;fn&lt;/code&gt;) is equal to &lt;code&gt;computeFunc&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;computeFunc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Circular computation detcted&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now doing the following throws an error instead of lagging the page until your tab crashes:&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reactor.js&lt;/span&gt;&lt;span class="dl"&gt;'&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;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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;// ERROR: Circular computation detected&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(()&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;num1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&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;num1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Practical Application - Mini Framework
&lt;/h2&gt;

&lt;p&gt;At this point I was going to see if I could describe how RxJs's approach differs from ours. Instead I think I'm going to show how we can turn our library into a mini framework, to illustrate the effectiveness of this approach.&lt;/p&gt;

&lt;p&gt;We often want frameworks to be fairly reactive - where changes to variables are reflected in the DOM and vice versa. Our reactive system is perfect for this. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code below available at: &lt;a href="https://codesandbox.io/s/reactor-p6-ynq3h"&gt;https://codesandbox.io/s/reactor-p6-ynq3h&lt;/a&gt;&lt;/em&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Reactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;computed&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./reactor.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./framework.js&lt;/span&gt;&lt;span class="dl"&gt;'&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;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Reactor&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;computed&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;num1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;num2&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;inputOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;rejectOn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;isNaN&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mutator&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&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;input1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&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="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputOptions&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;input2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&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="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;num2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;inputOptions&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;span&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&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="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;textContent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&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="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; + &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="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt; = &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="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;span&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our framework exposes 2 functions - &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;create&lt;/code&gt; which wrap &lt;code&gt;HTMLElement&lt;/code&gt;s in a class called &lt;code&gt;El&lt;/code&gt;. This class exposes the methods &lt;code&gt;bind&lt;/code&gt;, &lt;code&gt;append&lt;/code&gt;, and &lt;code&gt;on&lt;/code&gt;. With simple rules, we can create a 2-way binding between our reactive values and input elements. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;get&lt;/code&gt; simply uses &lt;code&gt;document.querySelector()&lt;/code&gt;. &lt;code&gt;create&lt;/code&gt; is a simple call  to &lt;code&gt;document.createElement()&lt;/code&gt;. &lt;code&gt;on&lt;/code&gt; is &lt;code&gt;.addEventListener()&lt;/code&gt; and &lt;code&gt;append&lt;/code&gt; is &lt;code&gt;.appendChild()&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;bind&lt;/code&gt; is the interesting one here.&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="nf"&gt;bind&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="nx"&gt;funcOrReactor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&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="c1"&gt;// grab reactor from function, if it isn't a reactor&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reactor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;funcOrReactor&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nx"&gt;Reactor&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;funcOrReactor&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;funcOrReactor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// if editing value, apply 2-way  binding&lt;/span&gt;
  &lt;span class="k"&gt;if &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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;value&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;e&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mutator&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mutator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;rejectOn&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rejectOn&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;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nx"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&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;// change property when reactive value changes&lt;/span&gt;
    &lt;span class="nx"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;_el&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="o"&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="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if &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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;textContent&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="nx"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;_el&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="o"&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// if not textContent or value, it's probably an attribute&lt;/span&gt;
    &lt;span class="nx"&gt;reactor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;_el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&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="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;// allow method to be chained&lt;/span&gt;
  &lt;span class="k"&gt;return&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;bind&lt;/code&gt; just adds a subscription unless the name is &lt;code&gt;value&lt;/code&gt; in which case it also tries to change the reactive value with an &lt;code&gt;eventListener&lt;/code&gt;. In such a case, we can mutate the value and possibly prevent updates with &lt;code&gt;rejectOn&lt;/code&gt;. Here we're using it to prevent non-valid numbers from getting in our reactive values.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I hope you learned a bit from this walk through. Special thanks to &lt;a href="https://github.com/ryansolid"&gt;Ryan Carniato&lt;/a&gt; and &lt;a href="https://github.com/jbreckmckye"&gt;Jimmy Breck-McKye&lt;/a&gt; who were instrumental in my understanding of all of this. I ended up rewriting Jimmy's library to fully understand some concepts. You can &lt;a href="https://github.com/EmNudge/trkl"&gt;see that here&lt;/a&gt; if you'd like to improve  your understanding of some concepts.&lt;/p&gt;

&lt;p&gt;If you're up to it, let me know what you liked and didn't, so that I can improve my technical writing for future publications!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>reactivity</category>
    </item>
    <item>
      <title>Invisible Unicode - Coding Deep Dive Episode #1</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Tue, 04 Aug 2020 00:52:49 +0000</pubDate>
      <link>https://dev.to/emnudge/invisible-unicode-coding-deep-dive-episode-1-20go</link>
      <guid>https://dev.to/emnudge/invisible-unicode-coding-deep-dive-episode-1-20go</guid>
      <description>&lt;p&gt;This is an article I first published on Dev.to in March of this year over here: &lt;a href="https://dev.to/emnudge/adventures-in-horrible-no-good-very-bad-variable-names-20ii"&gt;https://dev.to/emnudge/adventures-in-horrible-no-good-very-bad-variable-names-20ii&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I figured that the way the article was formatted might work better as a video, so I wrote a script, did some more research, recorded it, and made it into a video. Took about 5 months, but here it is!&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vHkM6RwA7Wk"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>unicode</category>
      <category>cdd</category>
    </item>
    <item>
      <title>Adventures in Horrible No Good Very Bad Variable Names</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Mon, 16 Mar 2020 18:21:02 +0000</pubDate>
      <link>https://dev.to/emnudge/adventures-in-horrible-no-good-very-bad-variable-names-20ii</link>
      <guid>https://dev.to/emnudge/adventures-in-horrible-no-good-very-bad-variable-names-20ii</guid>
      <description>&lt;p&gt;Recently I got a DM on &lt;a href="https://discordapp.com/"&gt;Discord&lt;/a&gt;. This person did not have much knowledge of JavaScript, but they had seen this rather interesting &lt;a href="https://jsfiddle.net/scp235o0/1/"&gt;snippet of JS&lt;/a&gt; which affected tweets on Twitter (now deleted). It changes a couple of very specific tweets, revealing text that wasn't previously there.&lt;/p&gt;

&lt;p&gt;They had run this JavaScript snippet in their dev console and wanted me to explain how it worked. For future reference, if you do not fully understand a JavaScript snippet, please do not do this. They can be malicious. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zS4Iz8EV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/ZSjcv7x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zS4Iz8EV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/ZSjcv7x.png" width="800" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How did this work? The tweets contained text that wasn't viewable by most font-sets. Many times these icons will show up as missing symbol boxes (▯ or □). These characters simply do not show at all.&lt;/p&gt;

&lt;p&gt;The JS snippet got the UTF code point for each character using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt"&gt;&lt;code&gt;String.prototype.codePointAt()&lt;/code&gt;&lt;/a&gt; and then converted it into an english character using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint"&gt;&lt;code&gt;String.fromCodePoint()&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;These special characters are ones returned from &lt;code&gt;String.fromCodePoint()&lt;/code&gt; when passed the first 4096 numbers starting from &lt;code&gt;0xe0000&lt;/code&gt; (917504). You can "see" all of them by running the following:&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;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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;4096&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCodePoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mh"&gt;0xe0000&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&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;Most dev tools will combine console logs into one output if they contain the same text. As these are distinct symbols, they will appear as 4096 separate logs. &lt;/p&gt;

&lt;p&gt;As they are distinct symbols, they do indeed contain length. In fact, we could probably artifically increase this article's "reading length" by filling it with these symbols. In between these two arrows are 100 characters. You can copy/paste it into dev tools and check its length to confirm.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;→󠀀󠀁󠀂󠀃󠀄󠀅󠀆󠀇󠀈󠀉󠀊󠀋󠀌󠀍󠀎󠀏󠀐󠀑󠀒󠀓󠀔󠀕󠀖󠀗󠀘󠀙󠀚󠀛󠀜󠀝󠀞󠀟󠀠󠀡󠀢󠀣󠀤󠀥󠀦󠀧󠀨󠀩󠀪󠀫󠀬󠀭󠀮󠀯󠀰󠀱󠀲󠀳󠀴󠀵󠀶󠀷󠀸󠀹󠀺󠀻󠀼󠀽󠀾󠀿󠁀󠁁󠁂󠁃󠁄󠁅󠁆󠁇󠁈󠁉󠁊󠁋󠁌󠁍󠁎󠁏󠁐󠁑󠁒󠁓󠁔󠁕󠁖󠁗󠁘󠁙󠁚󠁛󠁜󠁝󠁞󠁟󠁠󠁡󠁢󠁣←&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Note that using &lt;code&gt;String.prototype.length&lt;/code&gt; will actually print a length of &lt;code&gt;202&lt;/code&gt; instead of the expected &lt;code&gt;102&lt;/code&gt; (almost double) because every character after &lt;code&gt;0xFFFF&lt;/code&gt; (65,535) (called the BMP or &lt;a href="https://en.wikipedia.org/wiki/Plane_(Unicode)"&gt;Basic Multilingual Plane&lt;/a&gt;) exceeds the limit of JavaScript's UTF-16 strings. The arrows (in order to be displayed on smaller font sets) has a code point of &lt;code&gt;0x2192&lt;/code&gt; (8,594). To &lt;strong&gt;actually&lt;/strong&gt; retrieve the number of characters in a string, use a &lt;code&gt;for...of&lt;/code&gt; loop and take advantage of JS iterables!&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getNumChars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&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;length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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;const&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="o"&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;length&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;or, since the spread operator also works on iterables, a bit of a simpler method:&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="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In general, the intricacies of all of this is a bit more than what I'd like to get into. &lt;a href="https://mathiasbynens.be/notes/javascript-unicode"&gt;Mathias Bynens&lt;/a&gt; has a fantastic article on all this, which I highly advise you read for more information.&lt;/p&gt;

&lt;p&gt;You can quickly view a character's code point via the following function:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getCharHexCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;)&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;hex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;codePointAt&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="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`0x&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;hex&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;"Astral code points" (ones after &lt;code&gt;0xFFFF&lt;/code&gt;, such as &lt;code&gt;🡆&lt;/code&gt;) also contain a second index. It will return a code point that is relational to the actual code point defined by the following expression:&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;codePoint&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;codePoint&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mh"&gt;0xFFFF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;9216&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or the following function&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getAssociatedCodePoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codePoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codePoint&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mh"&gt;0xFFFF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// This is just here. No clue.&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;BASE_DIFF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9216&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// how many sets of 1024 numbers this is above 0xFFFF&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;codePoint&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mh"&gt;0xFFFF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// for every 1024 numbers, the difference jumps 1024&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;levelNum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;index&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;BASE_DIFF&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;levelNum&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;codePoint&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;I honestly do not know why this is so. Drop a comment if you have an explanation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;6/12/2020 EDIT&lt;/em&gt;: It turns out it's just the right surrogate pair.&lt;br&gt;
One would get the same result doing &lt;code&gt;'🡆'.codePointAt(1)&lt;/code&gt; as one would doing &lt;code&gt;'🡆'[1].codePointAt(0)&lt;/code&gt;. &lt;code&gt;codePointAt&lt;/code&gt; does not remove the right surrogate pair when retrieving the codepoint, just the left one.&lt;br&gt;
Read more about this stuff at: &lt;a href="https://dmitripavlutin.com/what-every-javascript-developer-should-know-about-unicode/#24-surrogate-pairs"&gt;https://dmitripavlutin.com/what-every-javascript-developer-should-know-about-unicode/#24-surrogate-pairs&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;While all this might be interesting to some, that wasn't why I wrote this article. I wanted to investigate variable names (hence the title). Could these special characters be used as variable names?&lt;/p&gt;
&lt;h2&gt;
  
  
  Variable Names And You
&lt;/h2&gt;

&lt;p&gt;Most people stick to standard conventions when making variable names in JS. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use English characters (no umlauts or diacritics).&lt;/li&gt;
&lt;li&gt;Start with &lt;code&gt;$&lt;/code&gt; for jQuery or &lt;code&gt;querySelector&lt;/code&gt;-based libraries.&lt;/li&gt;
&lt;li&gt;Start with &lt;code&gt;_&lt;/code&gt; for lodash/underscore or unused variable names.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Although these aren't physical limitations, people tend to stick to them. If one developer used diacritics, it would be difficult for developers without specific keyboard layouts to replicate them.&lt;/p&gt;

&lt;p&gt;What &lt;em&gt;I'm&lt;/em&gt; interested in is what are we &lt;em&gt;physically&lt;/em&gt; bound by. Could we use a number literal as a variable name, for instance? No. We are physically bound from doing that.&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="kd"&gt;const&lt;/span&gt; &lt;span class="mi"&gt;32&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="c1"&gt;// Uncaught SyntaxError: Unexpected number&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;32&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="c1"&gt;// Uncaught SyntaxError: Unexpected number&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some other things we can't use: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;reserved keywords

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;if&lt;/code&gt;, &lt;code&gt;while&lt;/code&gt;, &lt;code&gt;let&lt;/code&gt;, &lt;code&gt;const&lt;/code&gt;, etc&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;immutable global object properties in the global scope

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;NaN&lt;/code&gt;, &lt;code&gt;Infinity&lt;/code&gt;, and &lt;code&gt;undefined&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;variable names starting with unicode outside of the &lt;a href="https://codepoints.net/search?IDS=1"&gt;Unicode derived core property &lt;code&gt;ID_Start&lt;/code&gt;&lt;/a&gt; (excluding &lt;code&gt;$&lt;/code&gt; and &lt;code&gt;_&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Thanks again to &lt;a href="https://mathiasbynens.be/notes/javascript-identifiers-es6"&gt;Mathias Bynens&lt;/a&gt; for this info&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Mathias also provided an &lt;a href="https://mothereff.in/js-variables"&gt;online JavaScript variable name validator&lt;/a&gt; for if you would like to test things out yourself.&lt;/p&gt;

&lt;p&gt;One thing to note is that there is a difference in valid variable names for ES5, ES5-era engines, and ES6. We are using ES6.&lt;br&gt;
Mathias (yet again) has &lt;a href="https://mathiasbynens.be/notes/javascript-identifiers-es6"&gt;an article&lt;/a&gt; for this.&lt;/p&gt;

&lt;p&gt;What I was interested in was the odd stuff. A theoretical prank.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Theoretical Prank
&lt;/h2&gt;

&lt;p&gt;Every now and again this "meme" floats around where it advises pranking a coworker by replacing their semicolons with greek question marks (&lt;code&gt;;&lt;/code&gt; or &lt;code&gt;0x037E&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;These days, we have pretty good linters (in most languages) which will catch these. This prank can be found out very quickly. Let's try spicing things up a bit.&lt;/p&gt;

&lt;p&gt;What information from our knowledge of valid variable names can we use for our prank?&lt;/p&gt;

&lt;p&gt;Well firstly, &lt;a href="https://zalgo.org/"&gt;Zalgo text&lt;/a&gt; is fine. Zalgo text is the result of combining a bunch of diacritics to extend text outside of its vertical container. It tends to look like ṱ̶͇̭̖̩̯͚̋͛͗̋h̶̳̳̫͕̄͆̈̍̓̀̉ͅi̷̥̩̼̒̏s̷̰̣̽̇̀͆̀͠ and it's both valid unicode and a valid identifier.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ṱ̶͇̭̖̩̯͚̋͛͗̋h̶̳̳̫͕̄͆̈̍̓̀̉ͅi̷̥̩̼̒̏s̷̰̣̽̇̀͆̀͠&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ṱ̶͇̭̖̩̯͚̋͛͗̋h̶̳̳̫͕̄͆̈̍̓̀̉ͅi̷̥̩̼̒̏s̷̰̣̽̇̀͆̀͠&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// &amp;gt; 32&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since diacritics are valid in variable names, there's nothing really stopping us from combining them ad infinitum. This isn't very pleasant to look at, but it's still not what I had in mind for a prank.&lt;/p&gt;

&lt;p&gt;We previously discussed invisible characters. What if we could create invisible variable names? Are these valid?&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="kd"&gt;const&lt;/span&gt; &lt;span class="err"&gt;󠀀&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught SyntaxError: Invalid or unexpected token&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It doesn't seem so. And in case you were wondering, there is indeed a character there between &lt;code&gt;const&lt;/code&gt; and &lt;code&gt;=&lt;/code&gt;. If there wasn't, we would get a separate error.&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="kd"&gt;const&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught SyntaxError: Unexpected token '='&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could use the aforementioned tool to check valid variable names, but we'd be entering characters one by one. I need a way to automate this. I can copy Mathias's code, using a ton of regex and all that, or....&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`const &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; = 42;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&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="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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="http://linterrors.com/js/eval-is-evil"&gt;-"eval is evil"&lt;/a&gt; but we can make an exception for personal testing. Note that I'm specifically not using &lt;code&gt;let&lt;/code&gt; since passing a space to &lt;code&gt;isValidVariableName&lt;/code&gt; will return a false-positive if &lt;code&gt;let&lt;/code&gt; were used. After all, the following is valid:&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="kd"&gt;let&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As &lt;code&gt;let&lt;/code&gt; along with 8 other words were not considered reserved keywords outside of strict mode.&lt;/p&gt;

&lt;p&gt;With that in mind, let's get into a bit of width testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Width Testing
&lt;/h2&gt;

&lt;p&gt;I want to find valid variable names with thin, weird characters.  The easiest way to do this is via your eyes. Looking at characters is a pretty good way to tell how they look. Unfortunately, this is time-consuming. Especially for possibly over 1 million characters.&lt;/p&gt;

&lt;p&gt;Let's set up some test code&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSmallestChars&lt;/span&gt;&lt;span class="p"&gt;()&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;chars&lt;/span&gt; &lt;span class="o"&gt;=&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;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;Infinity&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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mh"&gt;0xFFFF&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCodePoint&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getStrSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&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="nx"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&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;chars&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 upper bound of &lt;code&gt;i&lt;/code&gt; is just small for the initial test. The important question is how do we find out how much space a character takes up? The question is font-specific and the DOM generally will not give the specific character size, but rather the space the parent &lt;code&gt;TextNode&lt;/code&gt; takes up.&lt;/p&gt;

&lt;p&gt;For this, we need to use &lt;code&gt;Canvas&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cnvs&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="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;canvas&lt;/span&gt;&lt;span class="dl"&gt;'&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;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;cnvs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2d&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getStrSize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&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;textMetric&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;measureText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&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;width&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;textMetric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actualBoundingBoxRight&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;textMetric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actualBoundingBoxLeft&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;height&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;textMetric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actualBoundingBoxAscent&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;textMetric&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;actualBoundingBoxDescent&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="na"&gt;width&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="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
        &lt;span class="na"&gt;height&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="nf"&gt;abs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;height&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;What you might notice is that we're declaring 2 variables outside of the scope of the function. This is &lt;em&gt;generally&lt;/em&gt; bad practice, but this function will be called thousands of times and I want to self-optimize a bit, just in case.&lt;/p&gt;

&lt;p&gt;If you have worked with &lt;code&gt;ctx.measureText&lt;/code&gt; before, you might also realize I'm not using its returned &lt;code&gt;width&lt;/code&gt; property, which should be exactly what I want. Some diacritics actually contain a negative width and the returned &lt;code&gt;width&lt;/code&gt; will only go as low as &lt;code&gt;0&lt;/code&gt;. I am calculating it myself to avoid such cases.&lt;/p&gt;

&lt;p&gt;You can view the resulting code on &lt;a href="https://jsfiddle.net/owrum5qk/2/"&gt;JS Fiddle&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code takes a while to run, but we (at least on my machine) get an array of 3 characters. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ba6bskx5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/WaqSQSo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ba6bskx5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/WaqSQSo.png" width="392" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yup. 3 spaces of varying widths. The canvas must have calculated these to be of zero width. Using these spaces, we can make some funky valid code.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ﾠ&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&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;ㅤ&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;58&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ﾠ&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="nx"&gt;ㅤ&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I'm excluding one of the spaces as it doesn't show up on some devices (such as Android phones or Windows 10 PC's). The other 2 spaces are known as &lt;a href="https://unicodelookup.com/#hangul%20filler/1"&gt;hangul filler&lt;/a&gt; characters. One is a half-width, which is why it's thinner.&lt;/p&gt;

&lt;p&gt;As an aside, while this test only ran through UTF-16 characters, I have done a test involving all unicode characters and gotten the same results.&lt;/p&gt;

&lt;p&gt;At this point, we've gotten the 2 characters that ES6 will allow us to &lt;em&gt;start&lt;/em&gt; a variable name with, but we haven't explored all the valid variable-naming characters. &lt;/p&gt;

&lt;p&gt;As discussed before, a number cannot be at the beginning of a variable name, although it can be anywhere after the first character.&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="kd"&gt;const&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught SyntaxError: Unexpected number&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// good&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;// Uncaught SyntaxError: Invalid or unexpected token&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="c1"&gt;// good&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our &lt;code&gt;isValidVariableName&lt;/code&gt; fails to check for this. We can use the same function, but pass in a valid character as the first symbol to fully test this out. In our code, let's change the following code:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSmallestChars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// snip...&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// snip...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSmallestChars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// snip...&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`h&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;char&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;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// snip...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this code we are automatically skipping over super valid symbols and only keeping ones that are "kinda valid". We are prepending &lt;code&gt;h&lt;/code&gt; to the symbol. This way, if it passes, it is valid only after the first character.&lt;/p&gt;

&lt;p&gt;Using this change, we get 51 symbols (vs the 3 we originally got).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1BpAfM2G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uCD31JL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1BpAfM2G--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uCD31JL.png" width="800" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The newline (&lt;code&gt;↵&lt;/code&gt; or &lt;code&gt;0x21B5&lt;/code&gt;) character is a false-positive. It is not that the newline character is a part of the variable, it is simply getting skipped over. It reads similar to the following:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;h&lt;/span&gt;
&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which, due to how ASI works, is valid code. Although, only &lt;code&gt;h&lt;/code&gt;  (not &lt;code&gt;h↵&lt;/code&gt;) has been set to &lt;code&gt;42&lt;/code&gt;. We need to modify &lt;code&gt;isValidVariableName&lt;/code&gt; a bit for this checking.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kinda&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="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;kinda&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`
                const h = 42;
                const h&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; = 42;
            `&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`const &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; = 42;`&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&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="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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;By already defining &lt;code&gt;h&lt;/code&gt; before we use the passed string, we can guarantee an error will be thrown if the ASI simply interprets this as whitespace.&lt;/p&gt;

&lt;p&gt;Let's also change the previous code to&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;getSmallestChars&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// snip...&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;isValidVariableName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// snip...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running it we get 27 array elements.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZKw4PF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/t0tZXiO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8ZKw4PF8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/t0tZXiO.png" width="800" height="44"&gt;&lt;/a&gt;&lt;br&gt;
That means 24 of our previously returned symbols were whitespace characters. Here are the 27 hex codes:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;symbols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x34F&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x5A2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x5BA&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x5C5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x17B4&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x17B5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x180B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x180C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x180D&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x200C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0x200D&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE00&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE02&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE03&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE04&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE05&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE06&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE07&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE08&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE09&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE0A&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE0B&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE0C&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE0D&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE0E&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0xFE0F&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's at this point that I might as well mention that I have been doing most of these tests on a MacBook. I switch off between a MacBook and a Windows 10 Desktop PC depending on where I am. Windows 10 comes with a font containing many more unicode characters than other devices (aside for a few Linux distros). &lt;/p&gt;

&lt;p&gt;We want our "prank" to affect the majority of users, so we won't be using the larger 119 characters that my Windows machine gave me and only sticking to the 27 that both machines seem to share.&lt;/p&gt;

&lt;p&gt;The first 9 characters are viewable on Windows' default font, so we're going to skip to the following 18.&lt;/p&gt;

&lt;p&gt;The first 2 characters (&lt;code&gt;0x200C&lt;/code&gt; and &lt;code&gt;0x200D&lt;/code&gt;) are &lt;a href="https://unicodelookup.com/#zero%20width/1"&gt;zero width joiner/non-joiners&lt;/a&gt;. &lt;code&gt;0x200B&lt;/code&gt;, the &lt;a href="https://unicodelookup.com/#zero%20width%20space/1"&gt;zero width space&lt;/a&gt; (and the one right behind the other 2) was not included. Probably because it's whitespace and not a valid variable name.&lt;/p&gt;

&lt;p&gt;The following 16 (from &lt;code&gt;0xFE00&lt;/code&gt; to &lt;code&gt;0xFE0F&lt;/code&gt;) are &lt;a href="https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block)"&gt;variation selectors&lt;/a&gt;. There are many more than 16, but the rest are passed &lt;code&gt;0xFFFF&lt;/code&gt; and thus would not come up in our search.&lt;/p&gt;

&lt;p&gt;Here are all those characters: &lt;code&gt;→‌‍︀︁︂︃︄︅︆︇︈︉︊︋︌︍︎️←&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Running this code with the full extent of unicode doesn't genarate vastly different results. This means our aforementioned invisible tweet characters are not valid variable names. However, Our new characters are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Put Into Action
&lt;/h2&gt;

&lt;p&gt;We went over a lot. We have 18 non-starting variable characters and 2 starting blank characters. All within UTF-16 (not that it's strictly needed).&lt;/p&gt;

&lt;p&gt;Now for the "prank". Let's create a &lt;a href="https://babeljs.io/"&gt;Babel&lt;/a&gt; transformer plugin.&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// counts the number of variables we have transformed&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Identifier&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="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// convert number to hexidecimal and split into array&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;indexes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// turn each hex into an invisible char&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;indexes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;codePoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xfe00&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nf"&gt;parseInt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hex&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fromCodePoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;codePoint&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// add these chars onto the node name&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;name&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;chars&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// increase the number of variables we have transformed&lt;/span&gt;
        &lt;span class="nx"&gt;index&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="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;This plugin will add invisible characters onto every variable name, making every variable unique. Passing this plugin to a babel transformation will render the code broken. The error messages will be even more cryptic, as nothing will seem to have changed.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9LrZovm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uHdPz39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9LrZovm7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/uHdPz39.png" width="496" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course fixing this code manually will be extraordinarily difficult, which is why I've produced the cure as well!&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;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&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;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;visitor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nc"&gt;Identifier&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="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newName&lt;/span&gt; &lt;span class="o"&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;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;char&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&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;codePoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;char&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;codePointAt&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;// if it's within this range, it's invisible.&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isInvisible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;codePoint&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mh"&gt;0xfe00&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;codePoint&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mh"&gt;0xfe0f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="c1"&gt;// only allow visible characters&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;isInvisible&lt;/span&gt;
        &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newName&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;span class="p"&gt;};&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I thought ending with a somewhat "practical" application of what we've found through researching unicode might be interesting. &lt;/p&gt;

&lt;p&gt;It goes without saying, but please don't &lt;em&gt;actually&lt;/em&gt; use the aforementioned babel transformation on an unsuspecting participant's code. This was all in good fun and learning. The resulting output can be extraordinarily aggravating to debug.&lt;/p&gt;

&lt;h4&gt;
  
  
  June 4th Edit:
&lt;/h4&gt;

&lt;p&gt;When discussing this post with a friend, we found it was possible to check valid variable characters using &lt;code&gt;regex&lt;/code&gt;. This brings with it a significant speed improvement, so I'd advise using it over &lt;code&gt;try{}catch{}&lt;/code&gt;.&lt;br&gt;
One can find if a character is a valid starting character with &lt;code&gt;/\p{ID_Start}/u.test(char)&lt;/code&gt; and if it's a valid "continuation" character with &lt;code&gt;/\p{ID_Continue}/u.test(char)&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>variables</category>
      <category>unicode</category>
    </item>
    <item>
      <title>Good Blogs Outside of Dev.to</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Sun, 08 Mar 2020 00:22:11 +0000</pubDate>
      <link>https://dev.to/emnudge/good-blogs-outside-of-dev-to-3kl8</link>
      <guid>https://dev.to/emnudge/good-blogs-outside-of-dev-to-3kl8</guid>
      <description>&lt;p&gt;Heyo! I like to write about seemingly difficult coding topics. This blog is specifically focused on JavaScript.&lt;/p&gt;

&lt;p&gt;There are some posts, however, that I don't end up writing. Not for lack of experience with the topic, but simply because they've been written much better than I could ever write them.&lt;/p&gt;

&lt;p&gt;The main problem with this is that my audience might not ever read these posts because they're unaware of them. In order to remedy that (and because I haven't written much in a while), I created this post.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;note:&lt;/strong&gt; The ordering of people is arbitrary&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://lihautan.com/blogs/"&gt;Tan Li Hau&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Fascinating articles on compilers, parsing, code-splitting, and bundlers.&lt;/p&gt;

&lt;p&gt;Some of my favorite articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lihautan.com/json-parser-with-javascript/"&gt;JSON Parser With JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lihautan.com/manipulating-ast-with-javascript/"&gt;Manipulating AST With JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lihautan.com/pause-and-resume-a-javascript-function/"&gt;Pause And Resume a JavaScript Function&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="http://cliffle.com/blog/"&gt;Cliff L. Biffle&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;More recently, Cliffle's blog has been about Rust and Wasm. This is the one non-JS blogger, but I'm including him here because of how much I value his posts.&lt;/p&gt;

&lt;p&gt;Some of my favorite articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://cliffle.com/p/dangerust/"&gt;Learn Rust The Dangerous Way&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cliffle.com/blog/bare-metal-wasm/"&gt;Making Really Tiny WebAssembly Graphics Demos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cliffle.com/blog/prefer-rust/"&gt;Prefer Rust to C/C++ for new code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://www.keithcirkel.co.uk/"&gt;Keith Cirkel&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;While he hasn't written much as of late, his 2015-2016 articles on ES6 are still useful today.&lt;/p&gt;

&lt;p&gt;Some of my favorite articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.keithcirkel.co.uk/metaprogramming-in-es6-symbols/"&gt;Metaprogramming In ES6 - Symbols&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.keithcirkel.co.uk/metaprogramming-in-es6-part-3-proxies/"&gt;Metaprogramming In ES6 - Proxies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.keithcirkel.co.uk/es6-template-literals/"&gt;ES6 Template Literals&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://tomdale.net/"&gt;Tom Dale&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;His articles are often linked to, and for good reason! He only has a few articles and they're fairly general, but all a good read.&lt;/p&gt;

&lt;p&gt;Some of my favorite articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tomdale.net/2017/07/adventures-in-microbenchmarking/"&gt;Adventures in Microbenchmarking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tomdale.net/2017/04/whats-the-deal-with-typescript/"&gt;What's The Deal With TypeScript?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tomdale.net/2017/04/making-the-jump/"&gt;How Desktop Era Frameworks Can Thrive on Mobile&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://overreacted.io/"&gt;Dan Abramov&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Dan is probably the most well known of the bunch. He works on react and blogs about it too, in addition to reflections of general dev "best" practices and stereotypes.&lt;/p&gt;

&lt;p&gt;Some of my favorite articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://overreacted.io/the-elements-of-ui-engineering/"&gt;The Elements of UI Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://overreacted.io/react-as-a-ui-runtime/"&gt;React As a UI Runtime&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://overreacted.io/algebraic-effects-for-the-rest-of-us/"&gt;Algebreic Effects For The Rest Of Us&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="http://www.wirfs-brock.com/allen/"&gt;Allen Wirfs-Brock&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;TC39 member and programming language expert. Most of his JS posts are rather old, but still just as fascinating. He delves deep into some areas that you wouldn't think relevant.&lt;/p&gt;

&lt;p&gt;Some of my favorite articles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.wirfs-brock.com/allen/posts/778"&gt;Some ECMAScript Explanations and Stories for Dave&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.wirfs-brock.com/allen/posts/228"&gt;Experimenting with Mirrors for JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.wirfs-brock.com/allen/posts/166"&gt;A JavaScript Optional Argument Hazard&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Others
&lt;/h2&gt;

&lt;p&gt;Do you have some others that you particularly like? Drop a comment to let others know!&lt;/p&gt;

</description>
      <category>blogs</category>
      <category>external</category>
      <category>javascript</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Lazy Iterators From Scratch</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Fri, 31 Jan 2020 18:05:01 +0000</pubDate>
      <link>https://dev.to/emnudge/lazy-iterators-from-scratch-2903</link>
      <guid>https://dev.to/emnudge/lazy-iterators-from-scratch-2903</guid>
      <description>&lt;p&gt;I really like functional programming paradigms. Not necessarily functional programming. I've never quite got into it.&lt;/p&gt;

&lt;p&gt;But things such as higher-order functions, pattern matching, immutable data structures, pure functions, and so on are really nice to use and reason about. These aspects allow for cleaner and readable code, but may come at the expense of performance if not implemented properly.&lt;/p&gt;

&lt;p&gt;One of the easiest ways to sacrifice performance for readable code in javascript is with the higher-order functions. They're fantastic, but you can land yourself in some situations that could have been avoided with a less functional approach.&lt;/p&gt;

&lt;p&gt;Let's create a bit of a contrived but somewhat practical example. We need to do some shopping. To simplify things, we won't include any named for the products, just the price. We will try to calculate which items we can afford to buy via filtering out the ones that go over the total.&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="c1"&gt;// constants&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;TAX_RATE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.08875&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;BASE_SHIPPING&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&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;BANK_BALANCE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//&lt;/span&gt;

&lt;span class="c1"&gt;// all the items we want to buy&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;itemPrices&lt;/span&gt; &lt;span class="o"&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;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="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&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;currTotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;BASE_SHIPPING&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;newPrices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;itemPrices&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;TAX_RATE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currTotal&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;BANK_BALANCE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;currTotal&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newPrices&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Did you catch the problem? No? Let's pretend our array had a thousand elements. A million elements, maybe. Let's also keep our bank balance the same. We're a child with a piggy bank and big dreams.&lt;/p&gt;

&lt;p&gt;Each method call takes in a higher-order function and loops through the entire array. Is there any way to stop looping prematurely? Yes, but not with this approach.&lt;/p&gt;

&lt;p&gt;We are checking if the current total is greater than our bank balance. Once the total exceeds the balance, there isn't really a need to continue. We know the rest of the items are not within our budget.&lt;/p&gt;

&lt;p&gt;(This wouldn't necessarily be the case if the items weren't sorted. They are in this snippet.)&lt;/p&gt;

&lt;p&gt;Let's now write the same code with a for-loop:&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="c1"&gt;// snip...&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newPrices&lt;/span&gt; &lt;span class="o"&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;const&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;itemPrices&lt;/span&gt;&lt;span class="p"&gt;)&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;priceWithTax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;TAX_RATE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currTotal&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;priceWithTax&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;BANK_BALANCE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;currTotal&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;priceWithTax&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="nx"&gt;newPrices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;priceWithTax&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// snip...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our object-oriented code, aside for the &lt;code&gt;keyword&lt;/code&gt;, is faster by virtue of not creating a new array each time. We combined both &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; into statements in our for loop. Only one array is created. &lt;/p&gt;

&lt;p&gt;But did you notice that keyword?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;break&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It lets us prematurely exit the loop. Not only are we no longer checking if we reached our total, but we also aren't even adding the tax! We have skipped 2 operations that we otherwise couldn't!&lt;/p&gt;

&lt;p&gt;The functional approach using &lt;code&gt;Array.prototype.map&lt;/code&gt; and &lt;code&gt;Array.prototype.filter&lt;/code&gt; are just less performant due to the very nature of the methods themselves.&lt;/p&gt;

&lt;p&gt;One thing you also may have noticed is that our less functional approach is almost objectively &lt;strong&gt;less readable&lt;/strong&gt;. It's harder to scan and realize what's going on. Yes, it's less performant, but it may need to be a sacrifice taken when writing clean code for smaller arrays where a couple of extra operations is insignificant.&lt;/p&gt;

&lt;p&gt;However, there is a way to satisfy the performance problem while still applying a clean-code/imperative paradigm. This is with &lt;strong&gt;lazy iterators&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lazy Iterators
&lt;/h2&gt;

&lt;p&gt;One thing that may seem obvious to use about these higher-order functions is that they do something when you call them. When you tell it to map, it maps. When you tell it to filter, it filters.&lt;/p&gt;

&lt;p&gt;What other way can we make these work? We can probably envision a system where the &lt;code&gt;filter&lt;/code&gt; method is provided another parameter - one that tells it when to stop iterating. This would involve moving the method provided to filter into a for loop.&lt;/p&gt;

&lt;p&gt;We can also probably envision a system where the &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt; are combined as we did in our object-oriented approach.&lt;/p&gt;

&lt;p&gt;This is all possible with lazy iterators. We can take in methods such as &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;filter&lt;/code&gt;, but not execute them until we're told to. We take the functions passed into these methods and execute them in a for loop in order to break iteration early.&lt;/p&gt;

&lt;p&gt;A lazy iterator library in JS might looks something like:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&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;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="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrIter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&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;newArr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrIter&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&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="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Although the code looks very similar to the functional version, it uses a for loop under the hood where all functions are executed on each element, one by one. This also provides some other benefits.&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="c1"&gt;// snip...&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrIter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;itemPrices&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// use lazy iter library&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newPrices&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrIter&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;TAX_RATE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;takeWhile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;n&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currTotal&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;BANK_BALANCE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nx"&gt;currTotal&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&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="nf"&gt;collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// snip...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;takeWhile&lt;/code&gt; is a method that stops the iteration when it returns false on a given element. Because every function gets executed once per element instead of each one iterating over the entire set, we can also ensure the &lt;code&gt;map&lt;/code&gt; is only getting executed for the elements returned.&lt;/p&gt;

&lt;p&gt;As it is an &lt;code&gt;iteratable&lt;/code&gt;, we can also use it in a for loop without collecting and then stop prematurely using &lt;code&gt;break&lt;/code&gt;, saving on function calls yet again, since the functions are only called when each element is retrieved.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&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;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="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&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="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;expensiveOperation&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;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// only called expensiveOperation once&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's Make It
&lt;/h2&gt;

&lt;p&gt;Well, this wouldn't be a "from scratch" article if we didn't go over how to make one. It's surprisingly simple.&lt;/p&gt;

&lt;p&gt;Let's first create our class.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&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;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&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;funcs&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing especially important here. We are storing the array provided to us and then creating an array to store all the functions that users will add via the methods provided.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// snip..&lt;/span&gt;

    &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;funcs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;map&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&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="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;funcs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;filter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&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="nf"&gt;takeWhile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;funcs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;take_while&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have functions that add the parameter to the funcs array, with a string identifying what kind of function via the &lt;code&gt;type&lt;/code&gt; property. You may also notice the &lt;code&gt;return this&lt;/code&gt; at the end of each function. This is to allow method chaining, but is not strictly necessary.&lt;/p&gt;

&lt;p&gt;These are the only 3 function methods we're going to provide. Other ones should be simply as trivial, but I'll leave the minutia up to you.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// snip...&lt;/span&gt;

    &lt;span class="o"&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="nx"&gt;iterator&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;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&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;arr&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="nx"&gt;item&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;So this might look a bit odd. It's not finished, don't worry.&lt;/p&gt;

&lt;p&gt;This here is a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator"&gt;&lt;code&gt;[Symbol.iterator]&lt;/code&gt;&lt;/a&gt; method. If there exists a &lt;code&gt;Symbol.iterator&lt;/code&gt; method that returns an iterator, the class/object is known as an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols"&gt;iterable&lt;/a&gt;, which lets us use it in &lt;code&gt;for&lt;/code&gt; loops and other areas where iterables can be used.&lt;/p&gt;

&lt;p&gt;We can alternatively create a generator instead of the weird mess hand-implementing the iterator-protocol would require. That's what the &lt;code&gt;*&lt;/code&gt; means. Any expression we &lt;code&gt;yield&lt;/code&gt; will be an item in our iterator. &lt;/p&gt;

&lt;p&gt;That means our class currently can be shoved into a for loop and give us the elements in our array. Since we could have done that without shoving the array into this class, this isn't especially helpful.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// snip...&lt;/span&gt;

    &lt;span class="o"&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="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;outer&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;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&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;arr&lt;/span&gt;&lt;span class="p"&gt;)&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&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;const&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="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;of&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;funcs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;map&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="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&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;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;filter&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;func&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;continue&lt;/span&gt; &lt;span class="nx"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;func&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;break&lt;/span&gt; &lt;span class="nx"&gt;outer&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="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="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;You'll find a bit of an odd coding style here, like how I use &lt;code&gt;continue&lt;/code&gt; instead of &lt;code&gt;else&lt;/code&gt;, but it's easy if you take it slowly. &lt;/p&gt;

&lt;p&gt;Essentially, we have 2 loops - one to loop over the array and an inner one to apply all the functions to each item.&lt;/p&gt;

&lt;p&gt;We are labeling the outer loop with &lt;code&gt;outer:&lt;/code&gt; in order to break out of both loops from the innermost one without making things a little too complicated.&lt;/p&gt;

&lt;p&gt;Take note of &lt;code&gt;continue outer&lt;/code&gt; and &lt;code&gt;break outer&lt;/code&gt;. This is how we skip out of the inner loop and perform some action &lt;code&gt;continue/break&lt;/code&gt; on the outer loop. A &lt;code&gt;filter&lt;/code&gt; would skip the outer loop from &lt;code&gt;yield&lt;/code&gt;ing the value, essentially filtering out the item. A &lt;code&gt;takeWhile&lt;/code&gt; would &lt;code&gt;break&lt;/code&gt; the outer loop, removing all subsequent items.&lt;/p&gt;

&lt;p&gt;We are going to use this iterator protocol to create our &lt;code&gt;collect&lt;/code&gt; method, finishing up our entire class.&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// snip...&lt;/span&gt;

    &lt;span class="nf"&gt;collect&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="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="c1"&gt;// snip...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yup. Simple as that. Since we are now an iterable, we can spread ourselves into an array. This lets us keep our code nice and simple.&lt;/p&gt;

&lt;p&gt;We can create other methods similar to &lt;code&gt;collect&lt;/code&gt;, such as &lt;code&gt;take(num)&lt;/code&gt; which accepts a number of elements to retrieve. It's simple enough to code, so I'll leave that up to you.&lt;/p&gt;

&lt;p&gt;Here is the class in its entirety:&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="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LazyIter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;arr&lt;/span&gt;&lt;span class="p"&gt;)&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;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arr&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;funcs&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;funcs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;map&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&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="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;funcs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;filter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&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="nf"&gt;takeWhile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;func&lt;/span&gt;&lt;span class="p"&gt;)&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;funcs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&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;take_while&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="k"&gt;return&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="nf"&gt;collect&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="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="o"&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="nx"&gt;iterator&lt;/span&gt;&lt;span class="p"&gt;]()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nl"&gt;outer&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;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&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;arr&lt;/span&gt;&lt;span class="p"&gt;)&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;item&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;const&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="nx"&gt;func&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;of&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;funcs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;map&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="nx"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;func&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;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;filter&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;func&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;continue&lt;/span&gt; &lt;span class="nx"&gt;outer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                    &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;func&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;break&lt;/span&gt; &lt;span class="nx"&gt;outer&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="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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Closing
&lt;/h1&gt;

&lt;p&gt;I don't usually make tutorials. My articles are more conceptual than anything.&lt;/p&gt;

&lt;p&gt;I wanted to write this one to outline the type of performance improvements that developers may want to focus on. While micro-optimizations and language-specific optimizations are never a very wise choice in JS, algorithmic improvements work across languages and are very difficult for the engine to optimize.&lt;/p&gt;

&lt;p&gt;A developer's primary concern should be code clarity, with performance coming at a close second, depending on the situation. When performance benefits can be achieved without sacrificing code clarity, there often isn't much of an excuse. &lt;/p&gt;

&lt;p&gt;If your goal is more important in your situation, the object-oriented approach will always be faster than using our abstraction class. It is simply much more difficult to read and reason about.&lt;/p&gt;

&lt;p&gt;EDIT: After writing this (and yes, after) I decided to go ahead and put a lazy iterable class &lt;a href="https://github.com/EmNudge/Lazy-Iter"&gt;on github&lt;/a&gt;. This one is made with TS, so there are some code changes and additions.&lt;/p&gt;

</description>
      <category>iterator</category>
      <category>javascript</category>
      <category>iterable</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Identifying Negative Zero</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Sat, 25 Jan 2020 01:19:40 +0000</pubDate>
      <link>https://dev.to/emnudge/identifying-negative-zero-2j1o</link>
      <guid>https://dev.to/emnudge/identifying-negative-zero-2j1o</guid>
      <description>&lt;p&gt;As usual, I like to delve into some of the weird or complicated bits of JS. The other week I was thinking about a way to possibly identify a  negative zero.&lt;/p&gt;

&lt;p&gt;Some of you may be taken aback. What is a negative zero? Can zero even be negative? It can according to the &lt;a href="https://en.wikipedia.org/wiki/Signed_zero"&gt;IEEE&lt;/a&gt;! This is a standard used for almost all languages in their number systems. Thusly, a lot of the "weirdness" in JS number systems is actually standard across other languages, too!&lt;/p&gt;

&lt;p&gt;Although, how would we know if the input we were receiving was &lt;code&gt;-0&lt;/code&gt; or &lt;code&gt;0&lt;/code&gt;? Does it matter? Not really, but it's a fun exercise.&lt;/p&gt;

&lt;p&gt;Let's first create the rules. We have a function called &lt;code&gt;isZeroNegative&lt;/code&gt; which accepts a single parameter. We must return &lt;code&gt;true&lt;/code&gt; if the zero is negative and &lt;code&gt;false&lt;/code&gt; if it is a positive zero. We can write whatever code we want inside the function.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isZeroNegative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// some code&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// default return&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Our Options
&lt;/h2&gt;

&lt;p&gt;It seems pretty simple, but you will find it a bit challenging. You might first think to check if it's below &lt;code&gt;0&lt;/code&gt;, as that's usually the definition of a negative number, but this won't do. The check will return &lt;code&gt;false&lt;/code&gt; even though it is negative. &lt;code&gt;-0 &amp;lt; 0 === false&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Math.sign()&lt;/code&gt; might be your next guess. Its very purpose, after all, is to let us know whether a number is negative or not. If you pass a negative number, it will return &lt;code&gt;-1&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; if it is positive. Unfortunately, it will return the same zero we passed in if the number is a zero, whether negative or positive. &lt;code&gt;Math.sign(-0) === -0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next option might be to just check if it's strictly equal to &lt;code&gt;-0&lt;/code&gt;. Easy enough! Unfortunately, not even strict equality is strict enough! &lt;code&gt;-0 === 0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We're running out of options quickly. We need to run our &lt;code&gt;-0&lt;/code&gt; through a system that won't spit out a zero. It needs to give us back a number lower or higher than that or just a different data-type altogether.&lt;/p&gt;

&lt;p&gt;What about stringification? We can call &lt;code&gt;.toString()&lt;/code&gt; on any number to get its string equivalent. We can then check for the negative sign. We can get the negative sign in &lt;code&gt;-4&lt;/code&gt; by doing &lt;code&gt;(-4).toString()[0]&lt;/code&gt;. Unfortunately, yet again, negative zero is one step ahead of us. Darn that negative zero!&lt;/p&gt;

&lt;p&gt;Doing &lt;code&gt;(-0).toString()&lt;/code&gt; will simply result in &lt;code&gt;"0"&lt;/code&gt;. Negative zero stringifies to just zero. &lt;/p&gt;

&lt;p&gt;Enough of the cat-and-mouse games. Let's review some &lt;em&gt;actual&lt;/em&gt; answers. Try to think of one your own. Remember what we said 3 paragraphs back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Actual Answers
&lt;/h2&gt;

&lt;p&gt;There are a couple of methods. These might not even be an exhaustive list, so feel free to try out other ideas!&lt;/p&gt;

&lt;p&gt;I first came across &lt;a href="http://www.wirfs-brock.com/allen/posts/128"&gt;this blog post&lt;/a&gt; when researching this problem. It's from Allen Wirfs-Brock, a person currently on tc39, but it was was written in 2011, so there may be more methods made available recently. I will be taking the first 2 solutions from there.&lt;/p&gt;

&lt;p&gt;The first solution we're going to explore is possibly the most performant as we don't change any data types. We work entirely within the number system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mathematics and the IEEE
&lt;/h3&gt;

&lt;p&gt;We should first think about what kind of mathematical application can we involve &lt;code&gt;-0&lt;/code&gt; in to affect the result? Addition or subtraction? No, those would both act similarly to &lt;code&gt;0&lt;/code&gt;. Multiplication or Division? Multiplication would give us a zero (either negative or positive) and so that leaves us right where we started. Division with the zero as the numerator brings the same problem as multiplication!&lt;/p&gt;

&lt;p&gt;What if we involve &lt;code&gt;-0&lt;/code&gt; as the denominator? Any number aside for another zero on the numerator would result in &lt;code&gt;-Infinity&lt;/code&gt;! We can check for &lt;code&gt;-Infinity&lt;/code&gt; pretty easily!&lt;/p&gt;

&lt;p&gt;We have to be sure it is only &lt;code&gt;-0&lt;/code&gt; on the denominator that can result in &lt;code&gt;-Infinity&lt;/code&gt;, however. &lt;a href="http://whereswalden.com/"&gt;Jeff Waldon&lt;/a&gt; provides &lt;code&gt;-Math.pow(2, -1074)&lt;/code&gt; as a counterexample. We can thusly add a strictly equals check to ensure we're dealing with a zero.&lt;/p&gt;

&lt;p&gt;Via this solution, our winning code is now.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isZeroNegative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;)&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;isZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;zero&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&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;isNegative&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;zero&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kc"&gt;Infinity&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;isNegative&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;isZero&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;Interestingly enough, we can now create a more full-proof &lt;code&gt;Math.sign()&lt;/code&gt; using the same sort of method. This one works the same as the old one, but now works well with zeros. As a side-effect, &lt;code&gt;Math.sign('')&lt;/code&gt; now returns &lt;code&gt;1&lt;/code&gt; instead of &lt;code&gt;0&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sign&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;NaN&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="kc"&gt;Infinity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;-&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;return&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="o"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Strictest Equality
&lt;/h3&gt;

&lt;p&gt;Let's go back to a previous attempt at a solution. We found that strict equality (&lt;code&gt;===&lt;/code&gt;) wasn't strict enough. What kind of equality is more strict than that? What about constants? If the engine can identify &lt;code&gt;-0&lt;/code&gt; as being different than &lt;code&gt;0&lt;/code&gt;, we may be able to use that somehow.&lt;/p&gt;

&lt;p&gt;Unfortunately, &lt;code&gt;const&lt;/code&gt; is &lt;strong&gt;too&lt;/strong&gt; strict. We can't reassign a constant variable in the same scope, no matter what. Even if we reassign it to what it already was. The mere presence of the &lt;code&gt;=&lt;/code&gt; operator is enough to trigger an error.&lt;/p&gt;

&lt;p&gt;What we're trying to do is something like the following.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isZeroNegative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&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;posZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;posZero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="kc"&gt;true&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="kc"&gt;false&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;This will, unfortunately, trip even if we receive a positive zero. As mentioned before, the presence of &lt;code&gt;=&lt;/code&gt; is enough to set things off.&lt;/p&gt;

&lt;p&gt;Are there any other constants in JS? Well there in fact are! Using &lt;code&gt;Object.freeze&lt;/code&gt;, we can make an object immutable.&lt;/p&gt;

&lt;p&gt;It is important to note that mutating a property on an object that has been frozen will not throw an error. We need that to happen. To do so, we will use the more direct &lt;code&gt;Object.defineProperty&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isZeroNegative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&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;posZero&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="nf"&gt;freeze&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;val&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="k"&gt;try&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="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;posZero&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;val&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="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&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="kc"&gt;true&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="kc"&gt;false&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;This will throw an error if the new value is anything other than &lt;code&gt;0&lt;/code&gt;!&lt;/p&gt;

&lt;h3&gt;
  
  
  Modern String Conversion
&lt;/h3&gt;

&lt;p&gt;Let's yet again approach a solution we dismissed earlier. While it is true that &lt;code&gt;(-0).toString()&lt;/code&gt; returns &lt;code&gt;"0"&lt;/code&gt;, there is a more modern stringifier - &lt;code&gt;.toLocaleString()&lt;/code&gt;. It's pretty powerful, but recently I came across &lt;a href="https://twitter.com/ManuelBieh/status/1220664413037965312"&gt;a tweet&lt;/a&gt; regarding how calling it on &lt;code&gt;Infinity&lt;/code&gt; will return the symbol ("∞"), not the normal stringified version ("Infinity").&lt;/p&gt;

&lt;p&gt;Calling &lt;code&gt;.toLocaleString()&lt;/code&gt; on &lt;code&gt;-0&lt;/code&gt; actually returns &lt;code&gt;"-0"&lt;/code&gt;! &lt;br&gt;
Using this finding, we can modify the code as follows:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isZeroNegative&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;zero&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&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;zero&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&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="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;-&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last one is the quickest and simplest, but possibly not the most performant, which may be important in situations where finding a negative zero is important.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Why would one even need to find a negative zero? I can't think of one off hand. The reason isn't necessary.&lt;/p&gt;

&lt;p&gt;This article was more so an investigation into thought processes. Solving problems is an extremely important skill as a software engineer. The way you investigate solutions can be more important than the solution itself.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>wtfjs</category>
      <category>negative</category>
      <category>ieee</category>
    </item>
    <item>
      <title>let, const, and my view</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Thu, 26 Dec 2019 07:38:05 +0000</pubDate>
      <link>https://dev.to/emnudge/let-const-and-my-view-3aa</link>
      <guid>https://dev.to/emnudge/let-const-and-my-view-3aa</guid>
      <description>&lt;p&gt;"Well this isn't going to be a controversial post" he said, wrongly.&lt;/p&gt;

&lt;p&gt;For those unaware, the title is in reference to a little discussion that spanned across web dev twitter and reddit on the 21st of December.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fx8mdpvfv5hzaxmt5tmez.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fx8mdpvfv5hzaxmt5tmez.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tweet was in reference to &lt;a href="https://www.reddit.com/r/reactjs/comments/edj1dr/what_is_javascript_made_of/" rel="noopener noreferrer"&gt;a reddit post of his&lt;/a&gt;, which linked to an article he wrote from his fantastic blog, &lt;a href="https://overreacted.io/" rel="noopener noreferrer"&gt;https://overreacted.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Many comments on the post critiqued a part of his article which mentioned, in reference to variable bindings, favoring &lt;code&gt;let&lt;/code&gt; and only using &lt;code&gt;const&lt;/code&gt; when needed. As people usually act in the opposite way, favoring &lt;code&gt;const&lt;/code&gt; and only &lt;code&gt;let&lt;/code&gt; when a mutation is needed, a lot of the comments on the post where in regards to that snippet.&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fl0g74i6j97sgjwspe7cr.jpg" 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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fl0g74i6j97sgjwspe7cr.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dan defended his views on twitter and had some people from TC39 backing him up - either presently or with links in the replies.&lt;/p&gt;

&lt;p&gt;A post which seemed to echo his views by a TC39 member is one by Jamie Builds: &lt;a href="https://jamie.build/const" rel="noopener noreferrer"&gt;https://jamie.build/const&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The post uses quite a bit of foul language, for anyone who is sensitive to that, but it's a fun read.&lt;/p&gt;

&lt;p&gt;My take? I'm a &lt;code&gt;const&lt;/code&gt; advocate. I hadn't left any reply on twitter since I tend not to use any social media (at least for social media purposes. I just post jokes on twitter).&lt;/p&gt;

&lt;p&gt;With that said, I wasn't going to make a post, but this has been banging around in my head for the past few days and it has gotten to the point where I have to write &lt;em&gt;something&lt;/em&gt; on the matter. There's a key point that I feel a lot of people are missing and I'd like to provide it.&lt;/p&gt;

&lt;p&gt;My posts usually tackle some of the trickier bits on JS, so this is a bit out of my field, but still something I'm going to try and cover.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;code&gt;const&lt;/code&gt; vs &lt;code&gt;let&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Right off the bat, what do they do? Why were they provided in ES6? Didn't we have &lt;code&gt;var&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;var&lt;/code&gt; is almost entirely out of use due to an aspect that many find to look much more like a bug. &lt;code&gt;var&lt;/code&gt; allows for semi-hoisting. I elaborate a bit on this in &lt;a href="https://dev.to/emnudge/how-for-loops-really-work-4lhj"&gt;my article about for loops&lt;/a&gt;, but essentially, the variable declaration is hoisted to the top of the current function/file scope.&lt;/p&gt;

&lt;p&gt;Additionally, &lt;code&gt;var&lt;/code&gt; is not constrained to block scopes, allowing it to hoist itself out of &lt;code&gt;for&lt;/code&gt; loops. These 2 annoying aspects brought us the 2 alternatives - &lt;code&gt;let&lt;/code&gt; and &lt;code&gt;const&lt;/code&gt;. &lt;code&gt;let&lt;/code&gt; can be seen as &lt;code&gt;var&lt;/code&gt;, but without those 2 "bugs", and &lt;code&gt;const&lt;/code&gt; can be seen as &lt;code&gt;let&lt;/code&gt;, but with constant variable bindings.&lt;/p&gt;

&lt;p&gt;The "constant variable bindings" and not "creates constant values" distinction is important. If you create a variable with &lt;code&gt;const&lt;/code&gt; that is assigned to some non-primitive data structure, the structure can be mutated, but the variable cannot be re-assigned. This distinction can be conveyed with a single sentence and it would be much easier to teach if people stopped teaching &lt;code&gt;const&lt;/code&gt; as something to create immutable data structures, but rather immutable bindings.&lt;/p&gt;

&lt;p&gt;As a quick example:&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;       &lt;span class="c1"&gt;// {} is a non-primitive&lt;/span&gt;
&lt;span class="nx"&gt;myObj&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EmNudge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// You can still mutate the object&lt;/span&gt;
&lt;span class="nx"&gt;myObj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;               &lt;span class="c1"&gt;// ERROR - you can't reassign it.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's all there is to it. It's good practice to not use &lt;code&gt;var&lt;/code&gt; unless you are &lt;a href="https://github.com/getify/You-Dont-Know-JS/blob/2nd-ed/get-started/ch2.md" rel="noopener noreferrer"&gt;Kyle Simpson&lt;/a&gt; (all jokes, he does make some nice observations on this very topic, though) and just use &lt;code&gt;const&lt;/code&gt; when you need to, right?&lt;/p&gt;

&lt;p&gt;Not exactly. Coming from &lt;code&gt;var&lt;/code&gt;, the first instinct is to use &lt;code&gt;let&lt;/code&gt;, but many javascript developers will advise you differently. First let's discuss &lt;em&gt;why&lt;/em&gt; people like Dan Abramov and others are pro-let preference.&lt;/p&gt;

&lt;h1&gt;
  
  
  prefer-&lt;code&gt;let&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;Dan Abramov actually &lt;a href="https://overreacted.io/on-let-vs-const/" rel="noopener noreferrer"&gt;wrote an article&lt;/a&gt; shortly after this debacle unfolded on his justifications. He also compared both sides, but again missed the point I see missing from most posts.&lt;/p&gt;

&lt;p&gt;Let's go through his points. His views seem to be inline with most people who share his perspective, so I won't be including anything from other sources.&lt;/p&gt;

&lt;h3&gt;
  
  
  Loss of intent
&lt;/h3&gt;

&lt;p&gt;Dan claims that prefer-&lt;code&gt;const&lt;/code&gt; means we won't be able to know if something has some importance in being constant. Perhaps we have some value for the amount of seconds in a day? This is a value that we'd want to notify developers about being constant.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confusion
&lt;/h3&gt;

&lt;p&gt;Dan also claims that he sees many beginners confuse &lt;code&gt;const&lt;/code&gt; with immutability. As mentioned before, &lt;code&gt;const&lt;/code&gt; only serves to make a constant &lt;strong&gt;binding&lt;/strong&gt;, not data structure, but that is not immediately obvious to a beginner. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pressure to avoid redeclaring
&lt;/h3&gt;

&lt;p&gt;This is actually an interesting one and a reason why I am an advocate for &lt;a href="https://github.com/tc39/proposal-do-expressions" rel="noopener noreferrer"&gt;do-expressions&lt;/a&gt; or at least using an IIFE in place occasionally. This can also be solved by separating some things into a function.&lt;/p&gt;

&lt;p&gt;Essentially, what Dan is saying is that people will often use the ternary operator instead of a mutable value and using an &lt;code&gt;if&lt;/code&gt; statement to redefine it.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;const&lt;/code&gt; ain't all it's cracked up to be
&lt;/h3&gt;

&lt;p&gt;The next 2 reasons are essentially that &lt;code&gt;const&lt;/code&gt; doesn't provide any real benefit. It doesn't prevent bugs and there isn't any performance benefit. Any benefit is already made by the engine, even with &lt;code&gt;let&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;So what's my defense?&lt;/p&gt;

&lt;h1&gt;
  
  
  prefer-&lt;code&gt;const&lt;/code&gt;
&lt;/h1&gt;

&lt;p&gt;I'm going to tackle these a bit out of order, so bear with me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance benefits
&lt;/h3&gt;

&lt;p&gt;Yes, there is no engine benefit that I am directly aware of. That's not why we advocate for &lt;code&gt;const&lt;/code&gt;, but I'll toss it up as a win for the &lt;code&gt;let&lt;/code&gt; people for now. The people who write browser engines happen to be very good at what they do. It leads to a lot of specific ways to write JS code, like &lt;a href="https://tomdale.net/2017/07/adventures-in-microbenchmarking/" rel="noopener noreferrer"&gt;"no js-specific micro optimizations"&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Confusion
&lt;/h3&gt;

&lt;p&gt;I think this is a bit of an annoying point. JS has &lt;strong&gt;many&lt;/strong&gt; weird parts to it and I would love if none of them existed, but we can't ignore them. Using &lt;code&gt;let&lt;/code&gt; in most cases will only prevent people from seeing &lt;code&gt;const&lt;/code&gt; right &lt;em&gt;now&lt;/em&gt; and this aspect is pointless while plenty of codebases &lt;em&gt;already&lt;/em&gt; do prefer-&lt;code&gt;const&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;const&lt;/code&gt; needs to be taught as constant &lt;strong&gt;bindings&lt;/strong&gt; and not constant &lt;strong&gt;values&lt;/strong&gt;. It's unfortunate that it's not immutable values, but &lt;a href="https://www.google.com/search?q=tant+pis" rel="noopener noreferrer"&gt;"tant pis"&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If someone is used to &lt;code&gt;var&lt;/code&gt; and declaration hoisting, &lt;code&gt;let&lt;/code&gt; may be confusing to them. Closures are confusing. Implicit coercion is confusing. &lt;br&gt;
Yes, the less confusing aspects introduced the better, but this is not one that we should try to avoid for reasons explained a bit more later.&lt;/p&gt;

&lt;h3&gt;
  
  
  No benefit
&lt;/h3&gt;

&lt;p&gt;I'm going to take an interesting stance and not argue wholly with this. &lt;code&gt;const&lt;/code&gt; is useful to me when used as a &lt;strong&gt;default&lt;/strong&gt;. If you use &lt;code&gt;const&lt;/code&gt; occasionally, you should only really use it when you need to. It's when you use it &lt;strong&gt;always&lt;/strong&gt; that the real benefit comes in.&lt;/p&gt;

&lt;p&gt;This will play a lot into the next and final point, which will need its own section.&lt;/p&gt;

&lt;h1&gt;
  
  
  Intention Has Been Moved
&lt;/h1&gt;

&lt;p&gt;Intent is &lt;strong&gt;not&lt;/strong&gt; lost, just moved. A big issue I have is with people assuming that developers are using &lt;code&gt;const&lt;/code&gt; to declare intent. In reality, people are using &lt;code&gt;let&lt;/code&gt; to declare intent. &lt;/p&gt;

&lt;p&gt;Let's backtrack a bit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Readability
&lt;/h3&gt;

&lt;p&gt;One of the favored aspects of a particular paradigm of programming is how easy it is to read someone else's code, as that's what you do most as a developer in many jobs. &lt;/p&gt;

&lt;p&gt;If the code is shorter, that's usually easier to read. If the code uses good variable names, that's usually easier to read. If it is declarative rather than specifically imperative, that's usually easier to read.&lt;/p&gt;

&lt;p&gt;One of the biggest time-savers in skimming code is reading intent. If I see someone's code using declarative function names, I know at least what their code is &lt;strong&gt;trying&lt;/strong&gt; to do. If it isn't doing what it says it's doing, I additionally know it's a bug.&lt;/p&gt;

&lt;h3&gt;
  
  
  Intent through code
&lt;/h3&gt;

&lt;p&gt;This extends to other parts as well - not just function names. Comments show intent. The type of &lt;code&gt;HOF&lt;/code&gt; you might use can show intent. Using backticks vs quotes for strings shows intent. A lot of things show intent and allow me to skim your code and better understand what's going on.&lt;/p&gt;

&lt;p&gt;In regards to variable declarations, &lt;a href="https://www.rust-lang.org/" rel="noopener noreferrer"&gt;&lt;code&gt;rust&lt;/code&gt;&lt;/a&gt; has immutability be &lt;em&gt;default&lt;/em&gt;. I much prefer this way because mutation is actually much more rare than variables made to clear up code.&lt;/p&gt;

&lt;p&gt;In rust, variables are declared with &lt;code&gt;let&lt;/code&gt;. If they're to be mutated late on, they're declared with &lt;code&gt;let mut&lt;/code&gt;. When I see &lt;code&gt;mut&lt;/code&gt;, I am expecting to see this variable change. I like this. &lt;code&gt;mut&lt;/code&gt; shows me intent to mutate. &lt;code&gt;const&lt;/code&gt; has a separate meaning, but the point is that variable immutability isn't something we need to bother showing intent behind. It's the natural way of things.&lt;/p&gt;

&lt;p&gt;When I changed to prefer-&lt;code&gt;const&lt;/code&gt;, I was first fairly reluctant. I had no idea how many of my variables were truly never changing. These days, my code contains so few &lt;code&gt;let&lt;/code&gt;s, you might not notice any outside of a &lt;code&gt;for&lt;/code&gt; loop unless you're &lt;strong&gt;really&lt;/strong&gt; searching for them.&lt;/p&gt;

&lt;p&gt;In reality, it is &lt;code&gt;let&lt;/code&gt; that shows intent, not the other way around (as every let-advocate seems to be insinuating or declaring outright). If I see &lt;code&gt;let&lt;/code&gt;, a fairly unusual keyword, I know to expect something to change soon. &lt;/p&gt;

&lt;h3&gt;
  
  
  You can still use &lt;code&gt;let&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If someone does &lt;em&gt;not&lt;/em&gt; want to use ternaries for a new variable, they can very well use &lt;code&gt;let&lt;/code&gt; and I will know to expect a mutation soon. If you use prefer-&lt;code&gt;let&lt;/code&gt;, I will not know to expect a change with an &lt;code&gt;if&lt;/code&gt; statement. You can also take this opportunity to use an intermediate function and still use &lt;code&gt;const&lt;/code&gt; without involving ternaries.&lt;/p&gt;

&lt;p&gt;prefer-&lt;code&gt;const&lt;/code&gt; does not mean leaving &lt;code&gt;let&lt;/code&gt;. You can still use &lt;code&gt;let&lt;/code&gt;, but only when you find it advantageous for the scenario.&lt;/p&gt;

&lt;p&gt;Want to &lt;em&gt;specify&lt;/em&gt; something as const? Use screaming case. &lt;code&gt;THIS_VARIABLE_NAME&lt;/code&gt; &lt;em&gt;already&lt;/em&gt; shows me something is specifically constant. I don't need &lt;em&gt;another&lt;/em&gt; keyword to indicate this. Using prefer-&lt;code&gt;const&lt;/code&gt; does not remove &lt;code&gt;const&lt;/code&gt; intent and instead provides us with a &lt;em&gt;new&lt;/em&gt; &lt;code&gt;let&lt;/code&gt; intent, which turns out to be &lt;em&gt;much&lt;/em&gt; more useful.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;As Dan Abramov says, it's usually preferable to stick with the conventions of a specific project rather than pioneer your own. Consistent code is cleaner code. &lt;/p&gt;

&lt;p&gt;Happy holidays!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>let</category>
      <category>const</category>
    </item>
    <item>
      <title>The Comma Operator and Operator Precedence in JavaScript</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Wed, 27 Nov 2019 20:05:00 +0000</pubDate>
      <link>https://dev.to/emnudge/the-comma-operator-and-operator-precedence-in-javascript-6hp</link>
      <guid>https://dev.to/emnudge/the-comma-operator-and-operator-precedence-in-javascript-6hp</guid>
      <description>&lt;p&gt;Let's take a look at an expression. Give you best guess for what it evaluates to:&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="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Some might say &lt;code&gt;76000&lt;/code&gt;, others might say it'll throw an error. In actuality, this expression is completely valid in JS and it evaluates to &lt;code&gt;0&lt;/code&gt;. How? The comma operator.&lt;/p&gt;

&lt;p&gt;The comma operator is the operator with the weakest "binding" in JS. Remember PEMDAS from math class?  Operators have their own order of operations, but it's instead referred to as bindings or &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence"&gt;"Operator Precedence"&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;MDN describes precedence as "Operators with higher precedence become the operands of operators with lower precedence". What this means is that if an operator (which has 2 operands) has a higher precedence, it is as if it is surrounded by  parentheses; it is more strongly &lt;em&gt;bound&lt;/em&gt; to the values to its right and/or left.&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="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt;                          &lt;span class="c1"&gt;// 0&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;000&lt;/span&gt;                      &lt;span class="c1"&gt;// 0&lt;/span&gt;

    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;getDay&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;          &lt;span class="c1"&gt;// some number  6 - 12&lt;/span&gt;
    &lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;getDay&lt;/span&gt;&lt;span class="p"&gt;)())&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// the same number&lt;/span&gt;

    &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;        &lt;span class="c1"&gt;// true&lt;/span&gt;
    &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;void &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;))&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="c1"&gt;// true&lt;/span&gt;

    &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;56&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="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="p"&gt;(((&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;56&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;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;       &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The levels of precedence for each is listed on &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence"&gt;the MDN page&lt;/a&gt; near the bottom,  right  after the example. If 2 operators have the same precedence, their associativity tells us whether to go right-to-left or left-to-right when evaluating them.&lt;/p&gt;

&lt;p&gt;The comma operator has the lowest precedence. It binds last. If you ever see a comma, you know it won't accidentally bind to some code that it shouldn't. &lt;/p&gt;

&lt;p&gt;So what does the comma do? It takes 2 expressions as operands and returns the rightmost one. It is left-to-right associative and we can therefore chain them. Here are some examples&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="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;               &lt;span class="c1"&gt;// 2&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="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;           &lt;span class="c1"&gt;// 8&lt;/span&gt;
    &lt;span class="mi"&gt;40&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="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;  &lt;span class="c1"&gt;// false &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that it specifically takes in expressions, not statements. That means we &lt;em&gt;can't&lt;/em&gt; put things like &lt;code&gt;let x = 4&lt;/code&gt; as one of the operands, but we &lt;em&gt;can&lt;/em&gt; put things like &lt;code&gt;x = 4&lt;/code&gt;. Declarations are statements, while assignments are expressions.&lt;/p&gt;

&lt;p&gt;What else is an expression? decrements, increments, and Function calls!&lt;/p&gt;

&lt;p&gt;This means the following is valid JS:&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&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;myFunc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;num&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;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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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="nf"&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="p"&gt;}&lt;/span&gt; 

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&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;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;myFunc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`result: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;result&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;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// 0&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="c1"&gt;// result: 8&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parentheses are required as the comma operator's low precedence would make us accidentally combine the assignment and the first expression.  Parentheses have the highest precedence, so they contrast nicely to the comma's lowest precedence.&lt;/p&gt;

&lt;p&gt;The one case where parentheses are not required is when  one approaches an "operator" of even  higher precedence, the semicolon. &lt;/p&gt;

&lt;p&gt;This allows us to leave the parentheses behind where semicolons are involved, such as in  loop headers.&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&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="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&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="p"&gt;}&lt;/span&gt; 

    &lt;span class="c1"&gt;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// 0&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="c1"&gt;// 4&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How is any of this useful? One of my favorite way is &lt;a href="https://dev.to/emnudge/js-code-golfing-how-to-ruin-everyone-s-day-40h3"&gt;code golfing&lt;/a&gt;. As long as we don't involve any statements, we can stuff an entire loop body into the header.&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;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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hey!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// hey&lt;/span&gt;
    &lt;span class="c1"&gt;// hey&lt;/span&gt;
    &lt;span class="c1"&gt;// hey&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we have a variable that is already defined and initialized, we can also just use a while loop.&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hey!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// hey&lt;/span&gt;
    &lt;span class="c1"&gt;// hey&lt;/span&gt;
    &lt;span class="c1"&gt;// hey&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One of the situations which the comma operator &lt;em&gt;would&lt;/em&gt; have been especially useful is for a replacement for a function body when it comes to arrow functions. Unfortunately, the  comma operator has an even lower precedence than &lt;code&gt;=&amp;gt;&lt;/code&gt; and so we require parentheses to separate them. This means we're not saving any  characters, as we're using &lt;code&gt;()&lt;/code&gt; and &lt;code&gt;,&lt;/code&gt; instead of  &lt;code&gt;{}&lt;/code&gt; and &lt;code&gt;;&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;It is only useful in arrow functions if you intend on returning a value, in which you are missing out on  a &lt;code&gt;return&lt;/code&gt; statement due to the arrow function's implicit return when no function body is present.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myFunc1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;func1 called&lt;/span&gt;&lt;span class="dl"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myFunc2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;func2 called&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="k"&gt;return&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;myFunc1&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;myFunc2&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="c1"&gt;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// func1 called&lt;/span&gt;
    &lt;span class="c1"&gt;// 3&lt;/span&gt;
    &lt;span class="c1"&gt;// func 2 called&lt;/span&gt;
    &lt;span class="c1"&gt;// 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Consclusion
&lt;/h1&gt;

&lt;p&gt;I hope you learnt a bit more about operator precedence and the power of manipulating  it. I often see people grouping operators where they otherwise wouldn't have to. Grouping operators can often make code more readable, but too many can just as well bring about expression and operator soup.&lt;/p&gt;

&lt;p&gt;Use your new found power wisely.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>comma</category>
      <category>operator</category>
      <category>precedence</category>
    </item>
    <item>
      <title>(a == 1 &amp;&amp; a == 2 &amp;&amp; a == 3) === true - Wait, hold on...</title>
      <dc:creator>EmNudge</dc:creator>
      <pubDate>Tue, 26 Nov 2019 18:44:10 +0000</pubDate>
      <link>https://dev.to/emnudge/a-1-a-2-a-3-true-wait-hold-on-2olk</link>
      <guid>https://dev.to/emnudge/a-1-a-2-a-3-true-wait-hold-on-2olk</guid>
      <description>&lt;p&gt;Some of you may recognize the problem in the title. It's a bit of a famous sample of &lt;a href="https://dev.to/emnudge/wtfjs-and-coercion-454e"&gt;wtfJS&lt;/a&gt;, explained very well by &lt;a href="https://codeburst.io/javascript-can-a-1-a-2-a-3-ever-evaluate-to-true-aca13ff4462d"&gt;Brandon Morelli in 2018&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The code sample is as follows:&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;What?!&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="c1"&gt;// logs: What?!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why does it work? Well the trick is in realizing that &lt;code&gt;a&lt;/code&gt; here is not a primitive. It's an object with a getter - pretending to be a primitive.&lt;/p&gt;

&lt;p&gt;So what happens when we even try to compare an object and a primitive? If we take a look at &lt;a href="https://www.ecma-international.org/ecma-262/10.0/index.html#sec-abstract-equality-comparison"&gt;the spec&lt;/a&gt; it says (by rules 8 &amp;amp; 9) that we try to coerce the object into a primitive. How? Via &lt;code&gt;ToPrimitive&lt;/code&gt;, a function defined in &lt;a href="https://www.ecma-international.org/ecma-262/10.0/index.html#sec-toprimitive"&gt;the spec&lt;/a&gt; as well.&lt;/p&gt;

&lt;p&gt;In short, it tries to coerce the object into a number. If that doesn't work, it tries to coerce it into a string. Let's try to coerce an object to a string and number.&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// NaN&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// [object Object]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Okay, so neither of those are helpful. How exactly is it coercing them?&lt;/p&gt;

&lt;p&gt;According to &lt;a href="https://www.ecma-international.org/ecma-262/10.0/index.html#sec-ordinarytoprimitive"&gt;the spec&lt;/a&gt;, it's calling &lt;code&gt;.valueOf&lt;/code&gt; to get the number and &lt;code&gt;.toString&lt;/code&gt; to get the string. If &lt;code&gt;.valueOf&lt;/code&gt; returns an object, it moves on to &lt;code&gt;.toString&lt;/code&gt;. If &lt;code&gt;.toString&lt;/code&gt; doesn't return a primitive, it will actually throw an error:  &lt;code&gt;Uncaught TypeError: Cannot convert object to primitive value&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;We can override them ourselves like so:&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="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="nf"&gt;valueOf&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="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nf"&gt;toString&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="mi"&gt;100&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;a&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;we got valueOf()!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;a&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;we got toString()!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// logs: we got valueOf()!&lt;/span&gt;

    &lt;span class="c1"&gt;// returning an object, so it will be skipped&lt;/span&gt;
    &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;valueOf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&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="p"&gt;{}&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;55&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;a&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;we got valueOf()!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;a&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;we got toString()!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// logs: we got toString()!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You see, we don't actually have to return a string or number in either. &lt;/p&gt;

&lt;p&gt;So how do we use this to solve our problem? We make one of the getters return a value and increment it.&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="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="na"&gt;val&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="nf"&gt;valueOf&lt;/span&gt;&lt;span class="p"&gt;()&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;val&lt;/span&gt;&lt;span class="o"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value incremented!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;return&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;val&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;We got it!&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="c1"&gt;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// value incremented!&lt;/span&gt;
    &lt;span class="c1"&gt;// value incremented!&lt;/span&gt;
    &lt;span class="c1"&gt;// value incremented!&lt;/span&gt;
    &lt;span class="c1"&gt;// We got it!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can do something similarly with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy"&gt;the &lt;code&gt;Proxy&lt;/code&gt; class&lt;/a&gt;, but taking advantage of the same concept.&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="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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;value&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;prop&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prop&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;valueOf&lt;/span&gt;&lt;span class="dl"&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;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;prop&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I won't go too into &lt;code&gt;Proxy&lt;/code&gt; in this article, as &lt;a href="https://www.keithcirkel.co.uk/"&gt;Keith Cirkel&lt;/a&gt; made a much better article on the subject over &lt;a href="https://www.keithcirkel.co.uk/metaprogramming-in-es6-part-3-proxies/"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In essence, we are defining a new object with a getter "trap" that returns the current value property and increments it if its &lt;code&gt;.valueOf()&lt;/code&gt; method is called. This is just a fancier way of doing something that we did much simpler just before.&lt;/p&gt;

&lt;p&gt;Regardless, is this impossible using strict equality? What if we were presented with the same example, but with triple equals?&lt;/p&gt;

&lt;h1&gt;
  
  
  Strict Equality
&lt;/h1&gt;

&lt;p&gt;Well actually, it's possible. But first, we have to nail down a few fundamentals.&lt;/p&gt;

&lt;p&gt;The first being the &lt;code&gt;window&lt;/code&gt; object. Any property on this object is automatically given to us as if it were defined in some global scope. As such, &lt;code&gt;window.parseInt&lt;/code&gt; is the same as just &lt;code&gt;parseInt&lt;/code&gt;, &lt;code&gt;window.alert&lt;/code&gt; is the same as just &lt;code&gt;alert&lt;/code&gt;, and so on. &lt;/p&gt;

&lt;p&gt;We can also define our own properties and seemingly create variables dynamically.&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;makeVariables&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;window&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="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&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="nf"&gt;makeVariables&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if &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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;if &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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&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;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baz&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;baz&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// 55&lt;/span&gt;
    &lt;span class="c1"&gt;// "hello"&lt;/span&gt;
    &lt;span class="c1"&gt;// Uncaught ReferenceError: baz is not defined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Side note - this is a bad idea. Don't do this. But we're going to need this for our own example.&lt;/p&gt;

&lt;p&gt;Next, we need to go over &lt;code&gt;Object.defineProperty&lt;/code&gt;. This function lets us define properties on objects with unique qualities. It feels new, but it actually works on IE9. &lt;/p&gt;

&lt;p&gt;This cool method lets us make a property &lt;em&gt;really&lt;/em&gt; constant, so people don't change it. It also lets us define a custom getter method! Things are starting to feel a bit familiar!&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myObj&lt;/span&gt; &lt;span class="o"&gt;=&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="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myObj&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;val&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="nf"&gt;get&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="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myObj&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myObj&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;myObj&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;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// 0.6492479252057994&lt;/span&gt;
    &lt;span class="c1"&gt;// 0.6033118630593071&lt;/span&gt;
    &lt;span class="c1"&gt;// 0.6033118630593071&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why is this better than the previous method? Well this time we don't have to rely on coercion!&lt;/p&gt;

&lt;p&gt;Let's combine the 2 things we just discussed to finalize our second example:&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="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value incremented!&lt;/span&gt;&lt;span class="dl"&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;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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;We got it!&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="c1"&gt;// logs:&lt;/span&gt;
    &lt;span class="c1"&gt;// value incremented!&lt;/span&gt;
    &lt;span class="c1"&gt;// value incremented!&lt;/span&gt;
    &lt;span class="c1"&gt;// value incremented!&lt;/span&gt;
    &lt;span class="c1"&gt;// We got it!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice! Now we have it working with strict equality!&lt;/p&gt;

&lt;p&gt;We unfortunately can't define a variable in the object itself (and then access it in the getter), but if we really don't want to pollute the scope, we can use closures and IIFEs in a really tricky way (credit goes to P35 from the &lt;a href="https://discord.gg/RYaesEz"&gt;SpeakJS&lt;/a&gt; discord server).&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="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&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="kd"&gt;function&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="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="o"&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;value incremented!&lt;/span&gt;&lt;span class="dl"&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;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="p"&gt;})());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but this obviously is a pretty messy example.&lt;/p&gt;

&lt;p&gt;What about &lt;code&gt;Proxy&lt;/code&gt;? Could we use it here? Unfortunately, &lt;code&gt;Proxy&lt;/code&gt; will not work with the &lt;code&gt;window&lt;/code&gt; object, so it doesn't help us in this instance.&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrap Up
&lt;/h1&gt;

&lt;p&gt;So when is this useful? Hardly ever.&lt;/p&gt;

&lt;p&gt;Well, there are some occasions. Have you ever encountered a really weird error when using a JS framework? Something like &lt;code&gt;Uncaught TypeError: Invalid property descriptor. Cannot both specify accessors and a value or writable attribute&lt;/code&gt;? &lt;/p&gt;

&lt;p&gt;Your framework is probably using Proxies and getter methods under the hood. They're useful, but only when things get complicated and you want to hide that underlying complexity.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>wtfjs</category>
      <category>coercion</category>
    </item>
  </channel>
</rss>
