Reference to possibly undefined variable

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Chris Beall

    Reference to possibly undefined variable

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

    Example: window.outerHei ght is defined by some browsers, but not others.
    It would therefore seem prudent, before using this variable, to do
    something like:
    if (typeof (window.outerHe ight) != "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.outerHei ght)
    By 'bad things" I mean that the whole script comes to a halt.

    2. Aside from something like:
    (typeof (window.outerHe ight) != "undefined" ) ? x = window.outerHei ght
    : 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

  • RobG

    #2
    Re: Reference to possibly undefined variable

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

    Yes, how else?
    [color=blue]
    >
    > Example: window.outerHei ght is defined by some browsers, but not others.
    > It would therefore seem prudent, before using this variable, to do
    > something like:
    > if (typeof (window.outerHe ight) != "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.outerHei ght)
    > By 'bad things" I mean that the whole script comes to a halt.[/color]

    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.
    [color=blue]
    >
    > 2. Aside from something like:
    > (typeof (window.outerHe ight) != "undefined" ) ? x = window.outerHei ght
    > : x = "undefined"
    > is there a more concise way of doing this?[/color]

    var x = window.outerHei ght || '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.outerHei ght != 'undefined'
    && x = window.outerHei ght){
    // do something with x
    }

    Or, since window.outerHei ght should be a number:

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

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

    Comment

    • RobG

      #3
      Re: Reference to possibly undefined variable

      RobG wrote:

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

      [...][color=blue][color=green]
      >> is there a more concise way of doing this?[/color]
      >
      > var x = window.outerHei ght || 'undefined';[/color]

      Which presumes window.outerHei ght 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.outerHei ght;
      if ( x != undefined )

      Whatever you think is more maintainable.

      [...][color=blue]
      > Or, since window.outerHei ght should be a number:
      >
      > var x;
      > if ( typeof window.outerHei ght == 'number'
      > && x = window.outerHei ght){
      > // do something with x
      > }[/color]

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

      if ( window.outerHei ght != undefined ){
      var x = window.outerHei ght;
      // 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 getComputedStyl e 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

      Comment

      • Chris Beall

        #4
        Re: Reference to possibly undefined variable

        RobG wrote:[color=blue]
        > Chris Beall wrote:
        >[color=green]
        >> If you want your code to be bulletproof, do you have to explicitly
        >> check for the existence of any possibly-undefined variable?[/color][/color]
        (snip)[color=blue][color=green]
        >> 2. Aside from something like:
        >> (typeof (window.outerHe ight) != "undefined" ) ? x =
        >> window.outerHei ght : x = "undefined"
        >> is there a more concise way of doing this?[/color]
        >
        >
        > var x = window.outerHei ght || '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:[/color]
        (snip)

        But I did say bulletproof.... :-)
        [color=blue][color=green]
        >> 3. Are the consequences of using an undefined variable actually
        >> documented in any authoritative place?[/color]
        >
        >
        > Yes, in the official ECMA documentation for JavaScript. Links to
        > various versions and formats are here:
        >
        > <URL:http://www.mozilla.org/js/language/>[/color]
        (snip)

        Aha! That's what I didn't find with Google.
        [color=blue]
        > 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.[/color]
        (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.
        [color=blue]
        >
        > But, even though an undeclared 'n' is OK at this point, it may
        > cause a script error later[/color]
        (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




        Comment

        • RobG

          #5
          Re: Reference to possibly undefined variable

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

          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@pd7tw2n o

          or


          <URL:http://groups-beta.google.com/group/comp.lang.javas cript/browse_frm/thread/37e9b705ece03d3 3/ac3ea134c9e8506 3?q=Can+I+check +if+an+object+e xists%3F&_done= %2Fgroup%2Fcomp .lang.javascrip t%2Fsearch%3Fq% 3DCan+I+check+i f+an+object+exi sts%3F%26start% 3D0%26scoring%3 Dd%26&_doneTitl e=Back+to+Searc h&&d#ac3ea134c9 e85063>

          --
          Rob

          Comment

          Working...