title: When a string is not a string? Unicode normalization weirdness in Javascript
body: <p>I have run into what is, to me, some serious weirdness with string behavior in Firefox when using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize" rel="noreferrer"><code>.normalize()</code></a> Unicode normalization function.</p>
  
  <p><a href="http://ruphus.com/unicodeNormalization.html" rel="noreferrer">Here</a> is a demo, view the console in Firefox to see the problem.</p>
  
  <p>Suppose I have a button with an id of "NFKC":</p>
  
  <pre class="lang-html prettyprint-override"><code>&lt;button id="NFKC"&gt;NFKC&lt;/button&gt;
  </code></pre>
  
  <p>Get a reference to that, easy enough:</p>
  
  
  
  <pre class="lang-js prettyprint-override"><code>document.querySelector('#NFKC')
  // &lt;button id="NFKC"&gt;
  </code></pre>
  
  <p>Now, since this button has an id of NFKC, which we can get at that string as follows:</p>
  
  <pre class="lang-js prettyprint-override"><code>document.body.querySelector('#NFKC').id
  // "NFKC"
  </code></pre>
  
  <p>Stick that string in a variable:</p>
  
  <pre class="lang-js prettyprint-override"><code>var s1 = document.body.querySelector('#NFKC').id
  </code></pre>
  
  <p>By way of comparison, assign the very same string to a variable directly:</p>
  
  <pre class="lang-js prettyprint-override"><code>var s2 = 'NFKC'
  </code></pre>
  
  <p>So of course:</p>
  
  <pre class="lang-js prettyprint-override"><code>s1 === s2
  // true
  </code></pre>
  
  <p>And:</p>
  
  <pre class="lang-js prettyprint-override"><code>s1 == s2
  // true
  </code></pre>
  
  <p>Now’s the part where my head explodes.</p>
  
  <p>To normalize a string, you pass one of <code>NFC</code>, <code>NFD</code>, <code>NFKC</code>, or <code>NFKD</code> to <code>.normalize()</code>, like this:</p>
  
  <pre class="lang-js prettyprint-override"><code>'á'.normalize('NFKC')
  // "á"
  </code></pre>
  
  <p>Of course, depending on the normalization form you choose, you get different codepoints, but whatever.</p>
  
  <pre class="lang-js prettyprint-override"><code>'á'.normalize('NFC').length == 1
  // true
  'á'.normalize('NFD').length == 2
  // true
  </code></pre>
  
  <p>But whatever. The point is, pass one of four strings corresponding to normalization forms to <code>.normalize()</code>, and you'll get a normalized string back.</p>
  
  <p>Since we know that <code>s1</code> (the string we retrieved from the DOM) and <code>s2</code> are THE SAME STRING (<code>s1 === s2</code> is <code>true</code>), then obviously we can use either to normalize a string:</p>
  
  <pre class="lang-js prettyprint-override"><code>'á'.normalize(s2)
  "á"
  // well yeah, because s2 IS 'NFKC'. 
  </code></pre>
  
  <p>Naturally, <code>s1</code> will behave exactly the same way, right?</p>
  
  <pre class="lang-js prettyprint-override"><code>'á'.normalize(s1)
   // RangeError: form must be one of 'NFC', 'NFD', 'NFKC', or 'NFKD'
  </code></pre>
  
  <p>Nope.</p>
  
  <p>So the question is: why does it appear that <code>s1</code> is not equal to <code>s2</code> as far as <code>.normalize()</code> is concerned, when <code>s1 === s2</code> is true?</p>
  
  <p>This doesn’t happen in Chrome, the only other browser I’ve tested so far.</p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>This was a bug in Firefox and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1145326" rel="noreferrer">has been fixed</a>.</p>