YaK:: WebLog #535 Topic : 2007-06-12 06.37.39 matt : javascript fun fact : "" == 0 == false [Changes]   [Calendar]   [Search]   [Index]   [PhotoTags]   
  [Back to weblog: pretention]  
[mega_changes]
[photos]

javascript fun fact: "" == 0 == false

A quick fun fact about JavaScript I learned last week.


Last week, I was pairing to fix a bug where passing in the boolean false didn't put "false" into the table cell on the web page like we expected; the cell was blank. We wrote a JSUnit test that looked like this:

function testDisplayBooleans()
{
    var widget = new Widget("name", "contactInfo");
    var cell = widget.createCell({"name": false});
    assertEquals("false", cell.innerHTML);
}

For code that looked something like this:

function createCell(name)
{
    var value = StringUtils.trim(name || "");
    var node;
    if (!value)
    {
      node = createBlankTextNode();
    }
    else
    {
      node = document.createTextNode(value);
    }

    return node;
}

The actual code uses Prototype and objects, but I've removed that syntax to keep things things focused.

We thought we saw the problem right away -- the "if (!value)" will always be hit if the name comes in as boolean false. We figured that check was to see if value was null or undefined, so we changed it to explicitly check for those sentinel values instead.

A bunch of tests blew up. Crap. Looking into it more deeply, we realized that our boolean false name was actually getting converted to "" on the first line! We were then confused -- the cell was still being created with an   inside of it. That meant that if(!"") evaluates to true. One of our coworkers more versed in javascript voodoo informed us, and we wrote a passing JSUnit test to prove it:

function testHasTheWorldGoneMad()
{
  assertTrue("" == false);
  assertTrue(0 == false);
  assertTrue("" == 0);
}

If you want to *really* test for equality, you need to use the === operator. That's *3* equal signs, illustrated by this test:

function testItsAMadMadMadMadMadMadMadMadMadMadWorld()
{
  assertFalse("" === false);
  assertFalse(0 === false);
  assertFalse("" === 0);
}

With this understanding, we made our test pass my modifying the code like so:

function createCell(name)
{
    var value = name;
    var node;

    if (isBlank(cellValue))
    {
      node = createTextNodeWithBlankSpace();
    }
    else
    {
     node = document.createTextNode(formatValue(value)));
    }

    return node;
}

function isBlank(value)
{
    return value === undefined || value === null || StringStuff.trim(value) === "";
}

function formatValue(value)
{
    if (value === true)
    {
      return "true";
    }

    if (value === false)
    {
      return "false";
    }

   return StringStuff.trim(value);
}

Hopefully this helps other people; we thought we were going crazier than usual for about an hour.

Discussion:

showing all 0 messages    

(No messages)

>
Post a new message:

   

(unless otherwise marked) Copyright 2002-2014 YakPeople. All rights reserved.
(last modified 2007-06-12)       [Login]
(No back references.)