In JavaScript, is there an easier way to check if a property of a property exists?
Is there an easy way to natively determine if a deep property exists within an object in JavaScript? For example, I need to access a property like this:
var myVal = appData.foo.bar.setting;
But there is a chance that either foo, foo.bar, or foo.bar.setting has not been defined yet. In Groovy, we can do something like this:
def myVal = appData?.foo?.bar?.setting
Is there a similar way to do this in JavaScript, without having to write a custom function or nested if statements? I've found this answer to be useful, but was hoping there was a more elegant and less custom way.
Solution 1:
I find this very convenient:
var myVal = (myVal=appData) && (myVal=myVal.foo) && (myVal=myVal.bar) && myVal.settings;
If a property exists, the next part of the sequence will be attempted.
When the expression before &&
evaluates to false, the next part of the expression will not be checked. If either of myVal.appData.foo.bar.settings
is not defined, the value of myVal
(undefined
( will evaluate to false
.
Solution 2:
Sorry, it's not great:
var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.setting;
Another option:
try {
var myVal = appData.foo.bar.setting;
} catch (e) {
var myVal = undefined;
}
The . operator is not really intended for accessing objects like this. Probably using a function would be a good idea.
Solution 3:
I find other approaches a bit immense. So, what would be the major drawback of the following approach:
// Pass the path as a string, parse it, and try to traverse the chain.
Object.prototype.pathExists = function(path) {
var members = path.split(".");
var currentMember = this;
for (var i = 0; i < members.length; i++) {
// Here we need to take special care of possible method
// calls and arrays, but I am too lazy to write it down.
if (currentMember.hasOwnProperty(members[i])) {
currentMember = currentMember[members[i]];
} else {
return false;
}
}
return true;
}
Basically, we define a method on the object (not necessarily) and that method takes the path to a nested object and returns existence confirmation, likeappData.pathExists("foo.bar.setting");
EDIT:
Check object[prop] == undefined
is not semantically correct since it will return false even if the property is defined although its value is undefined
; that is why I use hasOwnProperty
to check is the property defined. This might not be important if one needs to just fetch the value.