Reference to possibly undefined variable

C

Chris Beall

If you want your code to be bulletproof, do you have to explicitly check
for the existence of any possibly-undefined variable?

Example: window.outerHeight is defined by some browsers, but not others.
It would therefore seem prudent, before using this variable, to do
something like:
if (typeof (window.outerHeight) != "undefined") { do stuff that
refers to this variable }
else { work around the fact that the variable isn't defined }

1. Is this really necessary? Bad things seem to happen if even
relatively harmless use is made of an undefined variable, such as
document.write ("Height is " + window.outerHeight)
By 'bad things" I mean that the whole script comes to a halt.

2. Aside from something like:
(typeof (window.outerHeight) != "undefined") ? x = window.outerHeight
: x = "undefined"
is there a more concise way of doing this?

3. Are the consequences of using an undefined variable actually
documented in any authoritative place?

Chris Beall
 
R

RobG

Chris said:
If you want your code to be bulletproof, do you have to explicitly check
for the existence of any possibly-undefined variable?

Yes, how else?
Example: window.outerHeight is defined by some browsers, but not others.
It would therefore seem prudent, before using this variable, to do
something like:
if (typeof (window.outerHeight) != "undefined") { do stuff that refers
to this variable }
else { work around the fact that the variable isn't defined }

1. Is this really necessary? Bad things seem to happen if even
relatively harmless use is made of an undefined variable, such as
document.write ("Height is " + window.outerHeight)
By 'bad things" I mean that the whole script comes to a halt.

You must determine what, for the purpose of your script, are
"bad things". Usually a graceful exit is required such that the
user does not notice any lack of functionality or failure to
successfully complete an action.

Where a function can't be performed for some reason, either an
alternative should be offered (e.g. by a trip to the server to
accomplish what might otherwise have happened in the page) or
the functionality is not exposed at all.
2. Aside from something like:
(typeof (window.outerHeight) != "undefined") ? x = window.outerHeight
: x = "undefined"
is there a more concise way of doing this?

var x = window.outerHeight || 'undefined';

Which will fail if "window" is not defined, but I think we're
safe there. But of course you must now test x to see what
happened, so your next line will likely be:


if (x) {
// do something with x
}

So you may as well do:

var x;
if ( typeof window.outerHeight != 'undefined'
&& x = window.outerHeight){
// do something with x
}

Or, since window.outerHeight should be a number:

var x;
if ( typeof window.outerHeight == 'number'
&& x = window.outerHeight){
// do something with x
}
3. Are the consequences of using an undefined variable actually
documented in any authoritative place?

Yes, in the official ECMA documentation for JavaScript. Links to
various versions and formats are here:

<URL:http://www.mozilla.org/js/language/>

There are 129 references to "undefined", including how
'undefined' is treated in a variety of contexts. A useful
discussion of the topic you have raised is here:

<URL:http://cleancode.sourceforge.net/wwwdoc/codingRules/vr4.html>

In short:

A reference to an *undeclared* variable will cause your script
to error and terminate. A reference to an *undefined* variable
will return 'undefined'. What your script does with that is up
to you, but it may cause a script error on some subsequent step.

For example, suppose you try:

if(n) {...}

when 'n' is undeclared, your script will go belly-up. However,
if it has been declared but has not yet be defined, n will
return 'undefined' and the test will return 'false';

But, even though an undeclared 'n' is OK at this point, it may
cause a script error later - e.g.:

var n; // n declared but undefined;
var x = document.forms[n]; // x is undefined too
var y = document.forms[n].elements // script error...

The above will run until it attempts to evaluate:

...forms[n].elements

at which point it will error and terminate. :-(
 
R

RobG

RobG wrote:

Sorry, did a spell check and clicked post before I was ready!

[...]
var x = window.outerHeight || 'undefined';

Which presumes window.outerHeight is != 0, which it should not
be. Using OR sets x to the string 'undefined', so a subsequent
test of:

if (x != 'undefined')

can be used. Alternatively, you can use:

var x = window.outerHeight;
if ( x != undefined )

Whatever you think is more maintainable.

[...]
Or, since window.outerHeight should be a number:

var x;
if ( typeof window.outerHeight == 'number'
&& x = window.outerHeight){
// do something with x
}

Which leads back to the cleanest, most easily maintained version
which is:

if ( window.outerHeight != undefined ){
var x = window.outerHeight;
// do more stuff maybe
} else {
// get x some other way
// do stuff differently maybe
}

Which avoids a slower 'typeof' test (but the slowness may be
trivial).

Note that some numeric values also return their units, such as
using getComputedStyle to return an element's height, so even
though they might appear to be numeric, they return something
like "358px" or "55em", etc. so testing for undefined is
probably the most robust general test.
 
C

Chris Beall

RobG said:
var x = window.outerHeight || 'undefined';

Which will fail if "window" is not defined, but I think we're
safe there. But of course you must now test x to see what
happened, so your next line will likely be:
(snip)

But I did say bulletproof.... :)
Yes, in the official ECMA documentation for JavaScript. Links to
various versions and formats are here:

<URL:http://www.mozilla.org/js/language/>
(snip)

Aha! That's what I didn't find with Google.
In short:

A reference to an *undeclared* variable will cause your script
to error and terminate. A reference to an *undefined* variable
will return 'undefined'. What your script does with that is up
to you, but it may cause a script error on some subsequent step.

For example, suppose you try:

if(n) {...}

when 'n' is undeclared, your script will go belly-up.
(snip)

Precisely what I want to avoid. It appears that 'typeof' is the only
safe thing to use, as it will return 'undefined' for either an
undeclared or undefined variable.
But, even though an undeclared 'n' is OK at this point, it may
cause a script error later
(snip)

Understood. That's why I want to identify the situation up front and
adjust for it on the spot.

Net: typeof is the only bulletproof way. Using 'if' is also less obtuse
than using a logical OR. The performance impact is small (and not
relevant in my case).

Many thanks, Rob
Chris Beall
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top