Reference to possibly undefined variable

Discussion in 'Javascript' started by Chris Beall, Mar 1, 2005.

  1. Chris Beall

    Chris Beall Guest

    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
     
    Chris Beall, Mar 1, 2005
    #1
    1. Advertising

  2. Chris Beall

    RobG Guest

    Chris Beall wrote:
    > 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. :-(


    --
    Rob
     
    RobG, Mar 1, 2005
    #2
    1. Advertising

  3. Chris Beall

    RobG Guest

    RobG wrote:

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

    [...]
    >> is there a more concise way of doing this?

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


    --
    Rob
     
    RobG, Mar 1, 2005
    #3
  4. Chris Beall

    Chris Beall Guest

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

    (snip)
    >> 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:

    (snip)

    But I did say bulletproof.... :)

    >> 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/>

    (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
     
    Chris Beall, Mar 1, 2005
    #4
  5. Chris Beall

    RobG Guest

    Chris Beall wrote:
    [...]
    >
    > 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).
    >


    Not exactly, you don't have to test for 'typeof' explicitly.
    Read this thread, in particular Mike Winter's comments.


    news://inetbws1.citec.qld.gov.au:119/7wCUd.525795$6l.338062@pd7tw2no

    or


    <URL:http://groups-beta.google.com/group/comp.lang.javascript/browse_frm/thread/37e9b705ece03d33/ac3ea134c9e85063?q=Can+I+check+if+an+object+exists%3F&_done=%2Fgroup%2Fcomp.lang.javascript%2Fsearch%3Fq%3DCan+I+check+if+an+object+exists%3F%26start%3D0%26scoring%3Dd%26&_doneTitle=Back+to+Search&&d#ac3ea134c9e85063>

    --
    Rob
     
    RobG, Mar 1, 2005
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Mantorok Redgormor
    Replies:
    70
    Views:
    1,763
    Dan Pop
    Feb 17, 2004
  2. Mark

    possibly undefined behavior

    Mark, Jun 18, 2009, in forum: C Programming
    Replies:
    44
    Views:
    1,100
    Tim Rentsch
    Jun 22, 2009
  3. luser- -droog

    possibly undefined operation

    luser- -droog, Dec 30, 2010, in forum: C Programming
    Replies:
    12
    Views:
    499
    Jorgen Grahn
    Jan 2, 2011
  4. VK
    Replies:
    45
    Views:
    605
    Dr John Stockton
    Sep 12, 2006
  5. -Lost
    Replies:
    13
    Views:
    373
    Richard Cornford
    Jan 31, 2007
Loading...

Share This Page