3

我正在寻找的基本上是一个 hasOwnProperty() 或“in”函数,它是递归的,并向下查看链以查看对象中是否存在键或属性。

例如我有对象:

var user = {
  username: "Derpette",
  profile: {
    role: 'admin',
    sex: 'female',
    emails:['derpette42@derpmail.com']
    }
}

我想知道对象或其子对象中的任何位置是否有键/属性“角色”。所以我希望能够调用类似的东西user.hasProperty('role'),它会返回true

现在我正在使用带有断言链的 if 语句来检查,但它看起来并不干净,尤其是对于深层嵌套属性。

例如我会这样做:

if(user && user.profile && user.profile.role){
    //Manipulate/Use user.profile.role here
}

另一个用例示例是,如果我正在过滤来自客户端的 mongoDB 更新修饰符。我想确保他们没有更新自己的角色,所以我需要检查属性“角色”是否不在他们的 mongoDB 修饰符 json 对象中的某个位置。但它可能出现在修饰符的几个地方,因此在这种情况下,if 属性链接并不适用。

我需要编写自己的递归 hasOwnProperty 吗?我在想像 jquery 或 underscores.js 或 Sugar.js 这样的项目中应该已经存在这样的东西,但我似乎找不到它。

4

2 回答 2

4

您可以递归地执行此操作:

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;
}

用法:

var obj = recHasProp(user, 'role');
if (obj) {
    // obj.role exists, and obj is user or a child of user
}
于 2013-07-30T21:24:55.137 回答
2

我对此的看法,它并不漂亮,但它在几行中表现非常出色。

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;
};

用法示例(在您的情况下):

hasProp(user, 'profile.role');

Plunker: http ://plnkr.co/edit/CIePivi3XcTEugFzEUyt?p=preview

于 2015-03-13T07:23:28.940 回答