tags:

views:

676

answers:

10

Like you would do in php:

if (@$some_var_exists)
    // do stuff

How would you do something like this in Javascript without getting an error?

Thanks

EDIT: Thanks for the answers. However, the problem I'm trying to solve is how to check if a variable exists when it's deep in a object, for example:

if (someObj.something.foo.bar)
  // This gives an error in the browser if "someObj.something.foo" is not defined.
+10  A: 

To check if a variable is defined, you could do:

if(self.somevar) {
    ...
}

As pointed out by Mister in the comments, the self part is important here.

Or, if you wish to be more explicit, you could do:

if(typeof somevar != "undefined") {
    ...
}

The way you are checking the PHP var is also not very neat or really the best practice as the @ error suppressor is expensive and not necessary in this case. You could use isset like this:

if(isset($some_var_here)) {
    ...
}

EDIT:
For your more specific problem, I think @Ryan Watkins answer is the way to do it, although I'd have to wonder why you put yourself in such a position anyways. :)

Paolo Bergantino
I think you mean `typeof somevar != "undefined"` -- the OP seems to only want to act if the variable *does* exist. +1
ojrac
That's how I have it. I only had it as == for like a second. :x
Paolo Bergantino
The first example is not a good practice. You should always test if a variable has ever been initialized. eg: if (self.somevar) ...
Mister Lucky
Why is it bad practice? I don't think there's anything particularly wrong with it. What possible bugs can come up from just doing that?
Paolo Bergantino
try it on a page where that variable has not been defined.you will spawn an error. not so bad if all code is yours, but many devs eventually tie in scripts from multiple sources, therefore this detection is crucial. why not just preface self. for testing it? could save you a ton debug time?
Mister Lucky
Mm. Interesting. I checked it before answering because I was pretty sure it did spawn an error. It didn't. I just tried it again but it indeed does. Don't know what I was smoking. Touche kind sir. Answer updated.
Paolo Bergantino
No problems, glad to be of assistance.
Mister Lucky
Well the problem arised because we build a big JSON object on a page, and sometimes a property of the object can have "grandkids", but its not mission critical to have it. Basically I just want to get it if its there, otherwise no big deal. Does that make sense?? ;)
Infinity
+2  A: 

Simpler than that..

if(varname){ ... }

This applies to variables, not objects.

jerebear
That is not a good practice. You should be testing if the variable has ever been initialized first. if (self.varname) ... or if (typeof varname != "undefined")
Mister Lucky
A: 

Javascript will return false in an if statement if the object doesn't exist

var myObj = {};
if (myObj.someUnknown)
{
  // will not get here if someUnknown doesn't exist.
}
bendewey
Just a neat thing to know, if you use this upon some IE objects it can sometimes execute the method if one exists.
Mister Lucky
Really, thats interesting do you have a link...
bendewey
No, just know it from working with IE for way too many years. If another prime example of it comes up then will pass along. Another tidbit would be that if you have a getter for the property it calls them during that lookup process.
Mister Lucky
+10  A: 

Check each part of the chain:

if (someObj && someObj.something && someObj.something.foo && someObj.something.foo.bar) {
   // stuff
}

Because the expression is evaluated from left to right, and returns as soon as it finds false, it will not cause an error. So if "someObj" exists, but "sometObj.something" does not, it will return false and never execute the test for someObj.something.foo that would throw an error.

Ryan Watkins
This is good, as long as you know the someObj has been defined first.
Mister Lucky
Isn't that the first thing he checks?
Zack Mulgrew
If someObj has not been defined, you will get an error for trying to access that variable. If you preface it with the window || self scope you eliminate that issue, and as you're performing the lookup like you're second condition.
Mister Lucky
No you will not, because the first thing the example I provide does is check for the existence of someObj - if it is not defined, it will be false an the check for the 'someObj.something' will never be executed.run the code. it does not throw an error with an undefined object.
Ryan Watkins
Will you please put the code in a page and try for yourself first?Run that line of code, and that line only! :)
Mister Lucky
or, for quickness sake.. just put javascript:if(someObj)alert("foo"); in your address bar? :)
Mister Lucky
Fine, but he's likely got more code referring to that initial objectEx. this works:if (someObj }
Ryan Watkins
@Ryan — I'm seeing the same thing as Mister Lucky. Changing the initial `someObj` to `typeof someObj !== "undefined"` works, as does `window.someObj`, depending on scope.
Ben Blank
Infinity
+1  A: 

When testing for the existence of a variable you should never blindly test with that variables name. The same rings true when finding properties and methods of deeply nested objects.

With that in mind:

// error will occur if someObj has not ever been defined in your code.
if (someObj) {
  // someObj has been defined
}

You can workaround that and use minimal code by testing against the global scope, which in browsers it is the window level.

// safe way to test for global variable.
if (window.someObj) {
  // someObj has been defined
}

Another fine test for global variable would be using the builtin typeof method, however it gets a bit tedious to type out if you have to do it often enough.

// another safe method for testing a global variable
if (typeof someObj != "undefined") {
  // someObj has been defined
}

Now for the testing of deep nested objects (often used as pseudo-namespaces in JS).

// testing deep nested object
if (self.someObj && 
    someObj.something && 
    someObj.something.foo && 
    someObj.something.foo.bar) {
  // do something ...
}

Just two final quick notes for advanced coders:

Sometimes in IE I've noticed that doing that type of lookup / existence test has actually called the method if I was testing for it. eg:

// this is an example, I can't recall which actual methods did this off-hand
if (document.execCommand) {
  // resultant value of execCommand method gets used to pass/fail the conditional
}

And, finally a very mild side-effect of these type of existence lookups is that when you have a getter applied to that property, it will actually run the getter during the conditional testing.

// this code only runs in Firefox 2+
// and is provided for instructional purposes only
var foo = {
  get bar() { alert("bar getter was executed") }
};
if (foo.bar) {
  // a foo.bar property is defined
}
Mister Lucky
A: 
function isVarDefined(str) {
    try { 
        return (typeof eval(str) !== 'undefined');
    }
    catch(e) {
        return false;
    }
}

Pass the variable name as string. For example:

isVarDefined('someObj.something.foo.bar')

PS: Eval is evil. You should sanitize the value of str to contain only a variable name rather than some arbitrary executable code. Left as an exercise to you!

Chetan Sastry
+1  A: 
if (typeof somevar === "undefined") {
    // then the variable doesnt' exist
Scott Evernden
+3  A: 

The following should be pretty much bullet-proof, but is a hassle and only works if you know the whole chain in advance:

if ('undefined' !== typeof someObj &&
    'undefined' !== typeof someObj.something &&
    'undefined' !== typeof someObj.something.foo &&
    'undefined' !== typeof someObj.something.foo.bar) {
    // do some stuff
}

You might be better off to do as Chetan suggests and use a try/catch block instead:

try {
    if ('undefined' !== typeof someObj.something.foo.bar) {
        // do some stuff
    }
}
catch (e) {}
Andrew Hedges
+4  A: 

@Scott Evernden and @Andrew Hedges have the only completely correct answers so far. Just doing something like

if (variable)

or

if (someObj && someObj.something && ... && someObj.something.foo.bar)

is not correct in general, because if someObj.something.foo.bar exists, but is zero or false, the condition will be false. It will only work if all of the properties are objects (not numbers, booleans, or even strings) and someObj exists.

The only correct ways to check for existence in general, are typeof variable !== "undefined", variable !== undefined (if you know it's been declared), "property" in variable, or, depending on what you mean by "exists", object !== null. try/catch could also work, but that seems messy.

When you have a long chain, it's not necessary to check every step for the correct type/null/undefined/etc.; as long as every intermediate value is an object (not a number, string, or boolean that happens to have extra properties), they will evaluate to true.

if (typeof someObj !== "undefined" && someObj &&
    someObj.something &&
    someObj.something.foo &&
    typeof someObj.something.foo.bar !== "undefined") {
    // someObj.something.foo.bar exists, but you may need to check for null
}
Matthew Crumley
Mister Lucky
Yeah, it's like instead of learning from people who know more than them, some people vote up code that reinforces their own bad habits.
Andrew Hedges
A: 

If you need to do it a lot, a function version to get the property if it exists and return undefined otherwise is:

function propertyChain(root, chain) {
    var properties = chain.split(".");
    var obj = root;
    while (properties.length) {
        if (typeof obj === "undefined" || obj === null)
            return undefined;
        obj = obj[properties.shift()];
    }
    return obj;
}

so that:

if (propertyChain(someObj, 'something.foo.bar'))

is essentially a non-throwing version (assuming you've declared someObj) of:

if (someObj.something.foo.bar)
Miles