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.net/EcFLk/2/
But is there any easier/shorter way? Inline solutions (without using special function) would be great. Thanks.
This works :P
if ( $($($(x).prop('y')).prop('z')).prop('a') ) {
// code
}
Live demo: http://jsfiddle.net/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 && ...
).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With