Sunday, May 1, 2011

Javascript: undefined !== undefined ?

When I recently integrated Facebook Connect with Tersus, I initially received the error messages Invalid Enumeration Value and Handler already exists when trying to call Facebook API functions.

It turned out that the cause of the problem was

object.x === undefined

returning false when there is no property 'x' in 'object'.

I worked around the problem by replacing strict equality with regular equality in two Facebook functions:

FB.Sys.isUndefined = function(o) { return o == undefined;};  
FB.Sys.containsKey = function(d, key) { return d[key] != undefined;};

This made things work for me, but seems to hint at some sort of collision between Facebook's Javascript and my own.

Any ideas what could cause this?

Hint: It is well documented that undefined == null while undefined !== null. This is not the issue here. The question is how comes we get undefined !== undefined

From stackoverflow
  • The problem is that undefined compared to null using == gives true. The common check for undefined is therefore done like this:

    typeof x == "undefined"
    

    this ensures the type of the variable is really undefined.

  • A). I never have and never will trust any tool which purports to produce code without the user coding, which goes double where it's a graphical tool.

    B). I've never had any problem with this with FB connect. It's all still plain old javascript running in a browser and undefined===undefined wherever you are.

    In short, you need to provide evidence that your object.x really really was undefined and not null or otherwise, because I believe it is impossible for what you're describing to actually be the case - no offence :) - I'd put money on the problem existing in the Tersus code.

    Youval Bronicki : Thanks, annakata. Your skeptical answer made me revisit the issue and find the correct answer (see below).
  • That's a bad practice to use the == equality operator instead of ===.

    undefined === undefined // true
    null == undefined // true
    null === undefined // false
    

    The object.x === undefined should return true if x is unknown property.

    In chapter Bad Parts of JavaScript: The Good Parts, Crockford writes the following:

    If you attempt to extract a value from an object, and if the object does not have a member with that name, it returns the undefined value instead.

    In addition to undefined, JavaScript has a similar value called null. They are so similar that == thinks they are equal. That confuses some programmers into thinking that they are interchangeable, leading to code like

    value = myObject[name];
    if (value == null) {
        alert(name + ' not found.');
    }
    

    It is comparing the wrong value with the wrong operator. This code works because it contains two errors that cancel each other out. That is a crazy way to program. It is better written like this:

    value = myObject[name];
    if (value === undefined) {
        alert(name + ' not found.');
    }
    
  • It turns out that you can set window.undefined to whatever you want, and so get object.x !== undefined when object.x is the real undefined. In my case I inadvertently set undefined to null.

    The easiest way to see this happen is:

    window.undefined = null;
    alert(window.xyzw === undefined); // shows false
    

    Of course, this is not likely to happen. In my case the bug was a little more subtle, and was equivalent to the following scenario.

    var n = window.someName; // someName expected to be set but is actually undefined
    window[n]=null; // I thought I was clearing the old value but was actually changing window.undefined to null
    alert(window.xyzw === undefined); // shows false
    
    annakata : Ah ha! And *this* is the major reason why I'm against using the undefined property (as opposed to using typeof). Congrats on working through the bug. +1

0 comments:

Post a Comment

Note: Only a member of this blog may post a comment.