最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

jquery - How to avoid "the property of undefined" error without having huge if statement in JavaScript? - Stac

programmeradmin5浏览0评论

I usually find myself working with deep objects like this:

var x = {
  y: {
    z: {
      a:true
    }
  }
}

And somewhere in the code:

if( x.y.z.a === true ){
  //do something
}

And in some cases any of the x,y,z variables could be undefined, in which case you would get "Cannot read property * of undefined"

Potential solution is:

if( x && x.y && x.y.z && x.y.z.a === true ){
  //do something
}

jsfiddle: /

But is there any easier/shorter way? Inline solutions (without using special function) would be great. Thanks.

I usually find myself working with deep objects like this:

var x = {
  y: {
    z: {
      a:true
    }
  }
}

And somewhere in the code:

if( x.y.z.a === true ){
  //do something
}

And in some cases any of the x,y,z variables could be undefined, in which case you would get "Cannot read property * of undefined"

Potential solution is:

if( x && x.y && x.y.z && x.y.z.a === true ){
  //do something
}

jsfiddle: http://jsfiddle/EcFLk/2/

But is there any easier/shorter way? Inline solutions (without using special function) would be great. Thanks.

Share edited Mar 8, 2012 at 22:52 Sherzod asked Mar 8, 2012 at 22:43 SherzodSherzod 5,13110 gold badges50 silver badges67 bronze badges 4
  • The last one is the shortest one. For longer names, you can also use: var tmp=x; if(tmp && (tmp=tmp.verylongname) && (tmp=tmp.evenlongernameblabla) && (tmp=tmp.doyougetit)) { ... }. – Rob W Commented Mar 8, 2012 at 22:46
  • I would want to use a special function in this case. – Jesse Good Commented Mar 8, 2012 at 22:47
  • @Jesse can you give the example? – Sherzod Commented Mar 8, 2012 at 22:51
  • @shershams: FWIW, I added a couple to my answer. – T.J. Crowder Commented Mar 8, 2012 at 22:56
Add a ment  | 

2 Answers 2

Reset to default 8

Nope, you've already found the right way. Of course, you can use a try/catch block and handle the error after-the-fact, but I'd use the x && x.y && x.y.z && x.y.z.a solution.

(You don't need the === true unless you really want the condition to only be true when a is strictly equal to true and not when it's 1 or "hi", but from your question, I'm thinking you know that already.)


You've said you don't want to use a function for this, and I haven't felt the need for one either, but just for fits and giggles:

function ref(obj, names) {
    var rv = obj, index;
    if (names) {
        for (index = 0; rv && index < names.length; ++index) {
            rv = rv[names[index]];
        }
    }
    return rv;
}

Usage:

if (ref(x, ["y", "z", "a"]) === true) {
    // do something
}

Function calls are so cheap these days...

Or alternately:

function ref(obj) {
    var rv = obj, index;
    for (index = 1; rv && index < arguments.length; ++index) {
        rv = rv[arguments[index]];
    }
    return rv;
}

Usage:

if (ref(x, "y", "z", "a") === true) {
    // do something
}

...but on most JavaScript engines, that will be slower (arguments tends to be slow). But then again, you'd have to be doing it thousands of times in a loop for the speed to be an issue.

Or as Šime suggests, a single variable (I was avoiding the split, but it's not expensive):

function ref(obj, path) {
    var rv = obj, names = path.split("."), index;
    for (index = 0; rv && index < names.length; ++index) {
        rv = rv[names[index]];
    }
    return rv;
}

Usage:

if (ref(x, "y.z.a") === true) {
    // do something
}

Live example of all three | Live source

This works :P

if ( $($($(x).prop('y')).prop('z')).prop('a') ) {
    // code
}

Live demo: http://jsfiddle/Yw5th/

It's an ugly pattern, but at least it's an one-liner and the property names don't have to be repeated (unlike x && x.y && x.y.z && ...).

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论