5

How to check if a JavaScript variable has actually been declared?

This solution doesn't work in my case:

JavaScript check if variable exists (is defined/initialized)

Example:

(function(){
    var abc;
    alert(typeof abc === 'undefined') // true
})();

Same as:

(function(){
    alert(typeof abc === 'undefined') // true
})();

It produces true in both cases. I could do this:

(function(){
    var abc;

    var isDefined = false;
    try { isDefined = abc || !abc; }
    catch(e) {}
    alert(isDefined); // true
})();

It works, but I'm looking for anything better that this, x-browsers.

EDIT: I want to use it in a piece of dynamic code which runs via eval and checks if a certain variable exists in either local or global scope.

Cœur
  • 37,241
  • 25
  • 195
  • 267
avo
  • 10,101
  • 13
  • 53
  • 81
  • Can you describe your use case or at least the environment in which they will be applied, e.g., is it whether a function param has been declared or any variable? – Brett Zamir Mar 27 '14 at 02:24

2 Answers2

1

This question has been asked many times, the answer is "you can't" (other than using try..catch as in the OP).

You can check for properties of an object using in or hasOwnProperty, however both those require that you can access the object that you wish to test. Variables belong to a variable object (ES 3) or environment record (ES 5) of an execution context, and they aren't accessible so you can't check their properties.

The special case is the global object, because global variables (i.e. properties of the global environment record) are made properties of the global object, so you can do:

var global = this;
var foo;

// Declared but not initialised
foo in global // true
global.hasOwnProperty('foo'); // true

// Not declared or initialised
bar in global  // error
global.hasOwnProperty('bar'); // true

However, the hasOwnProperty method is not supported on the global object for versions of IE < 9.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • Why "you can't"? I actually posted a code that *can* do it. – avo Mar 27 '14 at 02:32
  • 1
    Which is why I answered the "I'm looking for anything better that this" part. Using try..catch isn't considered a good idea, better to understand why you want to do this. Often you can use properties of an object rather than variables. – RobG Mar 27 '14 at 02:47
1

You can detect this using "use strict" like this:

"use strict";
try {
    myVar = 7;
    console.log("myVar is "+myVar);
} catch(e) {
    console.log("error");
}

Run the script and it will print "error". Then comment out the "use strict" and run it again; it will print "myVar is 7".

Lee Jenkins
  • 2,299
  • 3
  • 24
  • 39
  • This depends on `"use script"` and still uses `try/catch`. The last code fragment in my question does it without strict mode. Is there a way of doing it without `try/catch`? – avo Mar 27 '14 at 02:40
  • 1
    That's not a good idea as it assigns a value to the variable in order to test it. Maybe better to try to read the value, e.g. `var a = myVar`. It "works" in strict mode because it doesn't allow implicit creation of global variables. – RobG Mar 27 '14 at 02:52
  • @RobG You're missing the point. If you use myVar in *any* way an error will be thrown. You could replace myVar=7 with if(myVar==0) and the code will throw an error if myVar has not been declared. – Lee Jenkins Mar 27 '14 at 03:01