Sign up ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

Is there a better or shorthand way to perform a check on whether or not a variable within (possibly several levels of) an object is null or undefined?

What I would currently do to check is:

if (typeof json !== 'undefined' || typeof json.data !== 'undefined' || typeof json.data.formkeys !== 'undefined') {}

Is there a shorthand way to check for whether or not "json.data.formkeys" is undefined without the concern that one or all of the higher level properties or the object itself might not currently exist?

share|improve this question
2  
I don't have the JS knowledge to tell you in detail, but using a try catch would likely solve this. Take a look here. –  SuperBiasedMan yesterday
    
Could you provide a bit more context — where the json is generated from, and what you intend to do with formkeys? –  200_success yesterday
    
I can see how in many circumstances that would be appropriate if I'm only looking to perform a task or not perform a task, so that's a great point. In a scenario where I'm going through a few logical checks however (i.e. an else or an else if) the try catch would simply fail... I guess I could place an else within the catch but I think that's probably a poor practice. –  Ian yesterday
    
@200_success You could replace it with lollipops if you want, I'm asking a higher level question about checking for the existence of embedded variables within a JS object. It doesn't matter what I plan on doing with that variable later, what matters is how to return a false instead of an error when json or data are undefined but only checking for the existence of formkeys. –  Ian yesterday

2 Answers 2

up vote 5 down vote accepted

There's a lot of ways to do this. Here's an exotic (and costly) one:

if(((json || {}).data || {}).formkeys !== void 0){}

As commented, a try-catch will work

// JS has function scope. foo starts its life as declared but undefined
// If the try-catch fails, foo will remain undefined.
try{ var foo = json.data.formkeys; } catch(){}

if(foo !== undefined){}

A longer and possibly better way to do it is to create a resolver function. Most frameworks I have encountered use some form of this in their getter functions so that getting a value from a half-complete path will just return undefined instead of throwing midway.

function resolve(path, root){
  root = root || window;
  return path.split('.').reduce(function(parent, child){
    // A quick check for brevity. You can replace this with a better check
    // and return logic.
    return parent && parent[child];
  }, root);
}

var foo = resolve('json.data.formkeys');

if(foo !== undefined){}
share|improve this answer
    
Looks great, and you've given me a few things to look up; I've never used the reduce method. I get what you're doing with the path being passed to the function but can you please explain the root thing? –  Ian yesterday
    
@Ian root is the object where you want to start looking. Without it, the function defaults to the global window (I assume it's a browser). You can pass any object as root, even midway down another object. reduce allows you to carry the result of the last iteration when iterating through the array. Normally used for aggregation, but there are plenty of creative uses for it. –  Joseph the Dreamer yesterday

This is one case where eval is not evil, so long as you guard your code:

function getValue(obj, propertyString) {
    if (!/[_$a-z0-9.]/.test(propertyString)) {
        throw new Error("Invalid propertyString");
    }

    try {
        return eval("obj." + propertyString);
    }
    catch (error) {
        return undefined;
    }
}

(sigh) A quote from Dr. Evil seems oddly appropriate for eval (Dr. Eval? ... Nah.):

Well it's true! It's true! You're semi-evil. You're quasi-evil. You're the margarine of evil. You're the Diet Coke of evil. Just one calorie, not evil enough.

Related: eval() isn’t evil, just misunderstood

share|improve this answer
    
Eval not evil!?.. but cool, I'll try that out. I think I'm going to have to run speed tests on all of these answers and report back! –  Ian 6 hours ago
1  
@Ian: eval is not not evil. It's just not always evil. –  Greg Burghardt 6 hours ago

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.