spacer spacer spacer

2007-04-19

Undefined redux

A reader from Maynard asks:

My understanding is that in js, if a variable is declared var foo, and then it is read without an explicit initializer or setter being called, the variable still has a value of undefined and an error is signaled. If that is so in all js dialects then I don’t see any reason why adding variable declarations [to a class declaration] should ever cause problems. I don’t see how it could affect inheritance, for example. Am I missing something?

Gentle reader,

Sadly, JavaScript has way too many ways something can be undefined, and the two cases you cite are not equivalent:

  1. A global variable can not be declared at all. If you reference it, it is an error.

  2. A global variable can be declared and not initialized. If you reference it, it is not an error, you will get as a value the sole member o the Undefined type. (Note that undefined is not a JS literal like true, false, or null. It is just a normal variable, that initially has an undefined value. You can set it to have a different value, and probably break lots of programs. I recommend using void 0 as the best way to get the undefined value.)

  3. A global variable can be declared and initialized to void 0. This is indistinguishable from 2.

  4. Note that global variables are just properties of the global object (typically bound to this at the top level, or self or window in a browser), so although it is an error to reference an undefined variable, if you ask for that variable as a property of the global object, it is not an error (and you will get the undefined value as a result). [It is not an error in Javascript to ask for a non-existent property of an object. But, because this can be the source of bugs (a type-oh in your code), our debug compile does warn you when you make such a reference.]

  5. If you want to know if a variable has been declared or not (without using try/catch or provoking a warning), you can use hasOwnProperty on the global object, or the in operator. [For the global object, they are equivalent.]

Here’s some examples illustrating the above:

js> foo
js: "<stdin>", line 2: uncaught JavaScript runtime exception: ReferenceError: "foo" is not defined.
js> var bar
js> bar
js> var bletch = void 0;
js> bletch
js> bletch === bar
true
js> this.foo
js> this.foo === void 0
true
js> this.hasOwnProperty('foo')
false
js> this.hasOwnProperty('bar')
true
js> 'foo' in this
false
js> 'bar' in this
true

Now, that all said, your original question was about a class instance variable. Classes are implemented as objects, so instance variables are properties. It is not an error to reference a non-existent instance variable. There is still the tiny distinction that you can discover whether or not the variable has been declared or not using the hasOwnProperty method or the in operator. If you can prove that no code tries to do that for the variable under consideration, and that the declaration will not shadow an inherited value, you can assume that adding the declaration is safe.

Post a comment

Thanks for signing in, . Now you can comment. (sign out)

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)


Remember me?


You are not signed in. You need to be registered to comment on this site. Sign in