If you expect YAHOO.Foo.Bar
to be a valid object, but want to make your code bulletproof just in case it isn't, then it can be cleanest to just put a try catch around it and let one error handler catch any missing segment. Then, you can just use one if
condition instead of four that will detect if the terminal property exists and a catch handler to catch things if the intermediate objects don't exist:
try {
if (YAHOO.Foo.Bar.xyz) {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// handle error here
}
or, depending upon how your code works, it might even just be this:
try {
// operate on YAHOO.Foo.Bar.xyz
} catch(e) {
// do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist
}
I particularly use these when dealing with foreign input that is supposed to be of a particular format, but invalid input is a possibility that I want to catch and handle myself rather than just letting an exception propagate upwards.
In general, some javascript developers under-use try/catch. I find that I can sometimes replace 5-10 if statements checking input with a single try/catch around a larger function block and make the code a lot simpler and more readable at the same time. Obviously, when this is appropriate depends upon the particular code, but it's definitely worth considering.
FYI, if the usual operation is to not throw an exception with the try/catch, it can be a lot faster than a bunch of if statements too.
If you don't want to use the exception handler, you can create a function to test any arbitrary path for you:
function checkPath(base, path) {
var current = base;
var components = path.split(".");
for (var i = 0; i < components.length; i++) {
if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) {
return false;
}
current = current[components[i]];
}
return true;
}
Example usage:
var a = {b: {c: {d: 5}}};
if (checkPath(a, "b.c.d")) {
// a.b.c.d exists and can be safely accessed
}