我经常发现自己正在使用这样的深层对象:
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/
但是有更简单/更短的方式吗?内联解决方案(不使用特殊功能)会很棒.谢谢.
不,你已经找到了正确的方法.当然,您可以使用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)