views:

5736

answers:

4

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

+19  A: 

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.

Wolfram Kriesing
A: 

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.

annakata
Thanks, annakata. Your skeptical answer made me revisit the issue and find the correct answer (see below).
Youval Bronicki
+3  A: 

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.');
}
Török Gábor
+9  A: 

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
Youval Bronicki
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
annakata