Thursday, April 12, 2012

Javascript: undefined !== undefined?


Update - As of October 2011, some browsers (Safari 5.1, Firefox 7) no longer seem to let you change window.undefined, but some still do (Chrome 14)



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


Source: Tips4all

7 comments:

  1. 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.

    ReplyDelete
  2. 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

    ReplyDelete
  3. 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.');
    }

    ReplyDelete
  4. I'd like to note something here for beginners that want to learn about undefined

    If you run the following code

    if( a !== undefined )
    alert(a)


    in situation where variable a HAS NEVER BEEN DEFINED (I mean there was no line var a; before),
    you will get an ERROR EXCEPTION and your script will STOP RUNNING.
    The only true way not to be thrown out of your script is to write

    if( typeof a != 'undefined' )
    alert(a)


    I hope I was clear enough

    ReplyDelete
  5. From - JQuery_Core_Style_Guidelines


    Global Variables:
    typeof variable === "undefined"
    Local Variables:
    variable === undefined
    Properties:
    object.prop === undefined

    ReplyDelete
  6. 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.

    ReplyDelete
  7. var a;

    typeof a === 'undefined'; // true
    a === undefined; // true
    typeof a === typeof undefined; // true
    typeof a === typeof sdfuwehflj; // true

    ReplyDelete