如何在Javascript中检查对象或其子对象是否具有属性/键?

3

我需要的其实是一个可以递归地查看对象中是否存在某个键或属性的 hasOwnProperty() 或 'in' 函数。

例如,我有以下对象:

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

我想知道在对象或其子对象中是否存在一个名为'role'的键/属性。

因此,我希望能够调用类似user.hasProperty('role')的东西,并返回true

目前,我正在使用if语句和一系列断言来检查,但这看起来并不干净,特别是对于深度嵌套的属性。

例如,我会这样做:

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

另一个使用此功能的例子是,如果我正在过滤来自客户端的mongoDB更新修饰符。我想确保他们没有更新自己的角色,因此我需要检查属性“role”是否在其mongoDB修改器JSON对象中的任何位置。但它可能在修饰符中的几个位置,所以在这种情况下,进行属性链接的if语句不起作用。
我需要编写自己的递归hasOwnProperty吗?我认为像jquery或underscores.js或sugar.js这样的项目中应该已经存在类似的东西,但我似乎找不到它。

我非常确定没有这样的函数。但是你可以很容易地编写一个能够实现此功能的函数。 - Ian
例如:http://jsfiddle.net/N82aZ/2/ - Ian
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
}

谢谢!我真的很喜欢这个 :) 点赞 - iulial

3

我的看法是,虽然不太好看,但在它所涉及的几行代码中表现非常高效。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接