79

Possible Duplicate:
How can I check whether a variable is defined in JavaScript?
Is there a standard function to check for null, undefined, or blank variables in JavaScript?

I have a script that occurs in two parts.

The first part sets up a var:

var pagetype = "textpage";

The 2nd part is a simple if statement:

if(pagetype == "textpage") {
//do something
};

Now the 2nd part, the if statement, appears on all pages of my site. But the first part, where the var is declared, only appears on some of my pages.

On the pages without the var I naturally get this error:

Uncaught ReferenceError: pagetype is not defined

So my question is: is there a way with JavaScript or JQ to detect if a var exists at all (not just if it has data assigned to it)?

I am imagining I would just use another if statment, eg:

if ("a var called pagetypes exists")....
Community
  • 1
  • 1
MeltingDog
  • 14,310
  • 43
  • 165
  • 295
  • 1
    `typeof`, `window.hasOwnProperty`, `if(var x)`... – John Dvorak Dec 19 '12 at 01:12
  • 1
    You will get many answers to this question, most of which I assume will be correct ... I voted this question up, because it's nice to see a 'proper' attempt at error handling... – Zak Dec 19 '12 at 01:13

6 Answers6

136

I suspect there are many answers like this on SO but here you go:

if ( typeof pagetype !== 'undefined' && pagetype == 'textpage' ) {
  ...
}
elclanrs
  • 92,861
  • 21
  • 134
  • 171
  • What about `if(var pagetype == "textpage")...`? – John Dvorak Dec 19 '12 at 01:13
  • 10
    @JanDvorak: Pretty sure that's not valid JS... – elclanrs Dec 19 '12 at 01:17
  • 2
    That doesn't test if `pagetype` has been declared, only that the type of its value is not undefined. – RobG Dec 19 '12 at 01:33
  • 1
    The question asks specifically for a test that a variable has been declared even if it has not been assigned to. So the if statement should return true even if just `var pagetype;` has been declared without assigning a value to it. At the moment it doesn't. – Bruno Dec 19 '12 at 01:34
  • @elclanrs If at the top of my script I declare the variable pagetype like so `var pagetype;` what will the following expression return `typeof pagetype`? The var exists but just has no value assigned to it. Therefore it follows that `typeof pagetype` cannot be used as a test for existence. – Bruno Dec 19 '12 at 01:52
  • @Bruno: I see what you mean now, but it doesn't matter in the end because the existence of the variable determines the "truthyness" of that statement and you can't test for existence any other way AFAIK. So it's reliable to test this way unless you know the variable it's been declared but not assigned or `null` then I would use `if ( pagetype == null )`. – elclanrs Dec 19 '12 at 01:56
  • I think we should use `undefined` instead of `'undefined'` in 2021. – Fauzan Edris Mar 09 '21 at 04:14
  • @FauzanEdris in 2021 this is still the right answer. `undefined` is actually just a variable with the value of `undefined`. Checking `typeof` against `'undefined'` checks for _existence_ too, not just for the value. – elclanrs Mar 09 '21 at 17:15
22

You can use typeof:

if (typeof pagetype === 'undefined') {
    // pagetype doesn't exist
}
Blender
  • 289,723
  • 53
  • 439
  • 496
9

For your case, and 99.9% of all others elclanrs answer is correct.

But because undefined is a valid value, if someone were to test for an uninitialized variable

var pagetype; //== undefined
if (typeof pagetype === 'undefined') //true

the only 100% reliable way to determine if a var exists is to catch the exception;

var exists = false;
try { pagetype; exists = true;} catch(e) {}
if (exists && ...) {}

But I would never write it this way

jermel
  • 2,326
  • 21
  • 19
4

To test for existence there are two methods.

a. "property" in object

This method checks the prototype chain for existence of the property.

b. object.hasOwnProperty( "property" )

This method does not go up the prototype chain to check existence of the property, it must exist in the object you are calling the method on.

var x; // variable declared in global scope and now exists

"x" in window; // true
window.hasOwnProperty( "x" ); //true

If we were testing using the following expression then it would return false

typeof x !== 'undefined'; // false
Bruno
  • 5,772
  • 1
  • 26
  • 43
  • 1
    This only works if `pagetype` is defined in the global scope – Paul S. Dec 19 '12 at 01:23
  • 2
    This also only works in browsers, but not, for example, Node.js . Try using `this` instead of `window`. – John Dvorak Dec 19 '12 at 01:27
  • @Bruno—your method a does not check for the existence of a variable, method b is only useful for global properties, some of which might be variables. – RobG Dec 19 '12 at 02:16
  • are global variables not user defined properties that are added to the global object? But yes you are correct. – Bruno Dec 19 '12 at 02:23
  • @Bruno What if you declare a variable inside of a function. That does not add it to the global object... – Ian Dec 19 '12 at 02:24
3

Before each of your conditional statements, you could do something like this:

var pagetype = pagetype || false;
if (pagetype === 'something') {
    //do stuff
}
Jason
  • 51,583
  • 38
  • 133
  • 185
  • assuming you don't mind defining `pagetype` as a side-effect, OFC. – John Dvorak Dec 19 '12 at 01:26
  • it's just one way to do it. this way it will at least default to failing the condition if it doesn't exist. – Jason Dec 19 '12 at 01:27
  • This won't work at all for `pagetype` having falsey values like `""`, `0`, etc. If `pagetype` is already declared and set as one of these values, you overwrite it with `false`, and would cause incorrect comparisons. – Ian Dec 19 '12 at 02:07
  • actually it won't. if you want the condition to fail if it doesn't match a particular string (as is the OP's case) then certainly `""` and `0` and `false` are all equivalent – Jason Dec 19 '12 at 02:39
3

It is impossible to determine whether a variable has been declared or not other than using try..catch to cause an error if it hasn't been declared. Test like:

if (typeof varName == 'undefined') 

do not tell you if varName is a variable in scope, only that testing with typeof returned undefined. e.g.

var foo;
typeof foo == 'undefined'; // true
typeof bar == 'undefined'; // true

In the above, you can't tell that foo was declared but bar wasn't. You can test for global variables using in:

var global = this;
...
'bar' in global;  // false

But the global object is the only variable object* you can access, you can't access the variable object of any other execution context.

The solution is to always declare variables in an appropriate context.

  • The global object isn't really a variable object, it just has properties that match global variables and provide access to them so it just appears to be one.
RobG
  • 142,382
  • 31
  • 172
  • 209