如果在JavaScript中没有巨大的if语句,如何避免"未定义的属性"错误?

She*_*zod 7 javascript jquery

我经常发现自己正在使用这样的深层对象:

var x = {
  y: {
    z: {
      a:true
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在代码的某处:

if( x.y.z.a === true ){
  //do something
}
Run Code Online (Sandbox Code Playgroud)

并且在某些情况下,任何x,y,z变量都可能未定义,在这种情况下,您将获得" 无法读取未定义的属性* "

可能的解决方案是

if( x && x.y && x.y.z && x.y.z.a === true ){
  //do something
}
Run Code Online (Sandbox Code Playgroud)

jsfiddle:http://jsfiddle.net/EcFLk/2/

但是有更简单/更短的方式吗?内联解决方案(不使用特殊功能)会很棒.谢谢.

T.J*_*der 9

不,你已经找到了正确的方法.当然,您可以使用try/catch块并在事后处理错误,但我会使用该x && x.y && x.y.z && x.y.z.a解决方案.

(你不需要=== true除非你真的希望条件只有在a严格等于true而不是它的时候才是真的,1或者"hi"从你的问题来看,我认为你已经知道了.)


你已经说过你不想使用这个功能了,我也没有觉得需要一个功能,但只是为了适应和咯咯笑:

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

用法:

if (ref(x, ["y", "z", "a"]) === true) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

功能调用现在这么便宜 ......

或者:

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

用法:

if (ref(x, "y", "z", "a") === true) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

...但是在大多数JavaScript引擎上,速度会慢一些(arguments往往很慢).但话说回来,你必须在一个循环中做数千次才能将速度变成一个问题.

或者Šime建议,一个变量(我正在避免split,但它并不昂贵):

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;
}
Run Code Online (Sandbox Code Playgroud)

用法:

if (ref(x, "y.z.a") === true) {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

所有三个活生生的例子 | 直播源