JavaScript: undefined !== undefined?
JavascriptJavascript Problem Overview
NOTE: As per ECMAScript5.1, section 15.1.1.3, window.undefined is read-only.
- Modern browsers implement this correctly. for example: Safari 5.1, Firefox 7, Chrome 20, etc.
- Undefined is still changeable in: 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 code and my own.
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
.
Javascript Solutions
Solution 1 - Javascript
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.
Solution 2 - Javascript
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
Solution 3 - Javascript
I'd like to post some important information about undefined
, which beginners might not know.
Look at the following code:
/*
* Consider there is no code above.
* The browser runs these lines only.
*/
// var a;
// --- commented out to point that we've forgotten to declare `a` variable
if ( a === undefined ) {
alert('Not defined');
} else {
alert('Defined: ' + a);
}
alert('Doing important job below');
If you run this code, where variable a
HAS NEVER BEEN DECLARED using var
,
you will get an ERROR EXCEPTION and surprisingly see no alerts at all.
Instead of 'Doing important job below', your script will TERMINATE UNEXPECTEDLY, throwing unhandled exception on the very first line.
Here is the only bulletproof way to check for undefined
using typeof
keyword, which was designed just for such purpose:
/*
* Correct and safe way of checking for `undefined`:
*/
if ( typeof a === 'undefined' ) {
alert(
'The variable is not declared in this scope, \n' +
'or you are pointing to unexisting property, \n' +
'or no value has been set yet to the variable, \n' +
'or the value set was `undefined`. \n' +
'(two last cases are equivalent, don\'t worry if it blows out your mind.'
);
}
/*
* Use `typeof` for checking things like that
*/
This method works in all possible cases.
The last argument to use it is that undefined
can be potentially overwritten in earlier versions of Javascript:
/* @ Trollface @ */
undefined = 2;
/* Happy debuging! */
Hope I was clear enough.
Solution 4 - Javascript
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.'); > }
Solution 5 - Javascript
From - JQuery_Core_Style_Guidelines
-
Global Variables:
typeof variable === "undefined"
-
Local Variables:
variable === undefined
-
Properties:
object.prop === undefined
Solution 6 - Javascript
var a;
typeof a === 'undefined'; // true
a === undefined; // true
typeof a === typeof undefined; // true
typeof a === typeof sdfuwehflj; // true
Solution 7 - Javascript
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 Facebook Connect. It's all still plain old JavaScript code 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.