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.
我正在寻找的基本上是一个hasOwnProperty()或'in'函数,它是递归的,并向下看链以查看对象中是否存在键或属性。
For example I have the object:
例如,我有对象:
var user = {
username: "Derpette",
profile: {
role: 'admin',
sex: 'female',
emails:['derpette42@derpmail.com']
}
}
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
.
我想知道对象或其子对象中的任何位置是否存在键/属性“角色”。所以我希望能够调用user.hasProperty('role')这样的东西,它会返回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.
现在我正在使用带有断言链的if语句进行检查,但它看起来并不干净,特别是对于深层嵌套属性。
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 coming 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.
另一个用例的例子是我是否正在过滤来自客户端的mongoDB更新修饰符。我想确保他们没有更新自己的角色,所以我需要检查属性'role'不在他们的mongoDB修饰符json对象中。但它可能位于修饰符中的一些位置,因此执行if属性链接对于此情况不起作用。
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.
我是否需要编写自己的递归hasOwnProperty?我认为像这样的东西应该已经存在于像jquery或underscores.js或sugar.js这样的项目中,但我似乎无法找到它。
2 个解决方案
#1
3
You 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
}
#2
2
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
#1
3
You 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
}
#2
2
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