created by Brian Leroux & Andrew Lunny. sparodically uncurated by David Trejo.

charAt is not the same as []

dec 15 , 2013

In case someone tells you it doesn't matter how you access characters in strings, they're wrong:


  'hello'[1]          // 'e'
  'hello'.charAt(1)   // 'e'

  'hello'[-1]         // undefined
  'hello'.charAt(-1)  // ''

What better "character" than the empty string to say "no such index"?

@rtoal


Local storage limitations

oct 7 , 2013

The local storage functionality in browsers is a bit limited and this can lead to some rather surprising behaviour.

  localStorage[0] = false;

  if (localStorage[0]) {
      console.log('wtf'); // runs?!
  }

When checking the value stored in localStorage, it appears that the boolean was silently converted to the string "false", which is truthy.

Turns out that this is one of those cases where it pays off to carefully read the specification, which states that local storage only accepts string values!

If you want to store an object or other type of value, you can serialize the data with JSON.stringify and load it again with JSON.parse.

@Overv of http://while.io


implicit getElementById

oct 2 , 2013

document.getElementById can be omitted in all major browsers, inclunding IE6+. This is non-standard, but all of them save the elements ids as globals.

    <div id="myId"></div>
    <script>
      alert(myId.id);         // --> myId
      alert(window.myId.id);  // --> myId
    </script>

Or do they? Let's search myId in the window object.

    // Way 1
    alert('myId' in window);  // --> true (right...)
    // Way 2
    var present = false;
    for(var i in window){
      if(i == 'myId'){
        present = true;
      }
    }
    alert(present);           // --> false (wat!)

Looks like all browsers create Shroedinger's globals, that are here and not here at the same time...

What happens to globals when an element with the same id is created?

    <script>
      global0 = 1;
    </script>

    <div id=global0></div>

    <script>
      global0.innerHTML = "global0";     // --> nothing happens
      alert(global0);                    // --> 1
    </script>

So implicit getElementById's can't overload global vars, be they native or custom. What about the other way? Well, it depends on how the global var is set.

Let's try with "window."

    <div id=global1></div>

    <script>
      global1.innerHTML = "global1";        // --> the div is updated
      console.log(global1);                 // --> the div
      window.global1 = 1;                   // Try to set the global var "global1"
      console.log(global1);                 // --> 1
    </script>

OK.

Let's try without any prefix.

    <div id=global2></div>

    <script>
      global2.innerHTML = "global2";    // --> the div is updated
      try{global2 = 1}                  // Try to set the global var "global2"
      catch(e){alert(e)}                // --> TypeError on IE < 9, ok on other browsers
      global2.innerHTML = "hum";        // --> div contains "hum" on IE < 9, nothing happens on other browsers
      console.log(global2);             // --> "[object]" on IE < 9, 1 on other browsers
    </script>

Weird.

And what happens if the global var is declared with "var" ?

    <div id=global3></div>

    <script>
      global3.innerHTML = "global3";    // --> Uncaught TypeError: Cannot set property 'innerHTML' of undefined (wtf...)
      console.log(global3);             // --> undefined (wtf?)
      var global3 = 1;                  // --> this breaks the two lines above (wtf!)
      console.log(global3);             // --> 1
    </script>

WAT.

@MaximeEuziere


Array Constructor2 is Very Undefined

sept 30 , 2013

Have you ever thought that Array(3) will return you an array of 3 undefined's, the same as [undefined,undefined,undefined]?

So try this:

    Array(3).forEach(function(elem) { console.log(elem); });

And you will get no result at all, however

    [undefined,undefined,undefined].forEach(function(elem) { console.log(elem); });

will give you 3 nice log entries.

Are the first example's undefined less defined than the second example's undefineds?

Not really. According to forEach spec: "callbackfn is called only for elements of the array which actually exist", and constructor spec says nothing about putting in any elements (even undefined).

@tomalec


Math.max() behaviour

aug 7 , 2013

Math.max() has an interesting behaviour, handling different JavaScript data types in different ways.


    Math.max(3, 0);           // 3
    Math.max(3, {});          // NaN
    Math.max(3, []);          // 3
    Math.max(3, true);        // 3
    Math.max(3, 'foo');       // NaN
    Math.max(-1, null);       // 0
    Math.max(-1, undefined);  // NaN

Now, let's focus on Booleans:


    Math.max(1, true);     // 1
    Math.max(0, true);     // 1
    Math.max(1, false);    // 1
    Math.max(-1, true);    // 1
    Math.max(-1, false);   // 0

And now, on Arrays:


    Math.max(-1, []);      // 0
    Math.max(-1, [1]);     // 1
    Math.max(-1, [1, 4]);  // NaN

So next time, watch out for what you pass into Math.max().

@gnclmorais

Math.max() typecasts all values to Numbers (Number(x)), e.g.:

Math.max(false, -1); // 0
Math.max(5, "10");   // 10

@ixti


Fork me on GitHub