What I am looking for is basically a hasOwnProperty() or 'in' function which is recursive and looks down the chain to see if a key or property exists in an object.
For example I have the object:
var user = {
username: "Derpette",
profile: {
role: 'admin',
sex: 'female',
emails:['[email protected]']
}
}
I want to know if there is a key/property 'role' anywhere in the object or its sub-objects.
So I want to be able to call something like user.hasProperty('role')
and it would return true
.
Right now I am using if statements with a chain of assertions to check but it doesn't seem clean, especially for deep nested properties.
For example I would do:
if(user && user.profile && user.profile.role){
//Manipulate/Use user.profile.role here
}
Another example of a use-case for this is if I am filtering mongoDB update modifiers ing from a client. I want to make sure they aren't updating their own role so I need to check that the property 'role' isn't somewhere in their mongoDB modifier json object. But it could be in a few places in a modifier so doing the if property chaining doesn't work well for this case.
Do I need to write my own recursive hasOwnProperty? I am thinking that something like this should already exist somewhere in a project like jquery or underscores.js or sugar.js but I can't seem to find it.
What I am looking for is basically a hasOwnProperty() or 'in' function which is recursive and looks down the chain to see if a key or property exists in an object.
For example I have the object:
var user = {
username: "Derpette",
profile: {
role: 'admin',
sex: 'female',
emails:['[email protected]']
}
}
I want to know if there is a key/property 'role' anywhere in the object or its sub-objects.
So I want to be able to call something like user.hasProperty('role')
and it would return true
.
Right now I am using if statements with a chain of assertions to check but it doesn't seem clean, especially for deep nested properties.
For example I would do:
if(user && user.profile && user.profile.role){
//Manipulate/Use user.profile.role here
}
Another example of a use-case for this is if I am filtering mongoDB update modifiers ing from a client. I want to make sure they aren't updating their own role so I need to check that the property 'role' isn't somewhere in their mongoDB modifier json object. But it could be in a few places in a modifier so doing the if property chaining doesn't work well for this case.
Do I need to write my own recursive hasOwnProperty? I am thinking that something like this should already exist somewhere in a project like jquery or underscores.js or sugar.js but I can't seem to find it.
Share Improve this question asked Jul 30, 2013 at 21:17 DsykoDsyko 1,51415 silver badges27 bronze badges 2- I'm pretty sure there isn't one. But you could easily make a function that does so – Ian Commented Jul 30, 2013 at 21:21
- For example: jsfiddle/N82aZ/2 – Ian Commented Jul 30, 2013 at 21:24
2 Answers
Reset to default 4You could do this recursively:
function recHasProp(obj, prop) {
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
if (p === prop) {
return obj;
} else if (obj[p] instanceof Object && recHasProp(obj[p], prop)) {
return obj[p];
}
}
}
return null;
}
Usage:
var obj = recHasProp(user, 'role');
if (obj) {
// obj.role exists, and obj is user or a child of user
}
My take on this, it's not pretty, but it's very performant in the few lines that it is.
function hasProp(obj, propPath, i) {
if (typeof(i) === 'undefined' && !(i=0)) {
propPath = propPath.split('.');
}
if (typeof(obj[propPath[i]]) !== 'undefined') {
return (++i && i !== propPath.length) ? hasProp(obj[propPath[i - 1]], propPath, i) : true;
}
return false;
};
Usage Example (in your case):
hasProp(user, 'profile.role');
Plunker: http://plnkr.co/edit/CIePivi3XcTEugFzEUyt?p=preview