在 JavaScript 中,是否有更简单的方法来检查属性的属性是否存在?

IT技术 javascript
2021-03-08 18:36:01

有没有一种简单的方法可以本机确定 JavaScript 中的对象中是否存在深层属性?例如,我需要访问这样的属性:

var myVal = appData.foo.bar.setting;

但是有可能 foo、foo.bar 或 foo.bar.setting 尚未定义。在 Groovy 中,我们可以这样做:

def myVal = appData?.foo?.bar?.setting

在 JavaScript 中是否有类似的方法可以做到这一点,而无需编写自定义函数或嵌套的 if 语句?我发现这个答案很有用,但希望有一种更优雅、更少定制的方式。

6个回答

我觉得这很方便:

var myVal = (myVal=appData) && (myVal=myVal.foo) && (myVal=myVal.bar) && myVal.settings;

如果属性存在,则将尝试序列的下一部分。

当表达式 before 的&&计算结果为 false 时,将不会检查表达式的下一部分。如果其中一个myVal.appData.foo.bar.settings未定义,myVal( undefined( ( )的值将评估为false.

@Pointyvar myVal = appData && foo && bar && settings不会产生预期的结果。看我之前的评论。
2021-04-22 18:36:01
@Pointy:子赋值是为了避免重复属性名称,以便整体代码长度为 O(N) 而不是 O(N^2)。我自己会尝试在长度开始重要时切换到自定义函数。
2021-04-25 18:36:01
括号内的那些“子分配”没有理由。JavaScript 返回序列的最后一个表达式的实际值,否则返回false它不会像其他具有类似短路运算符的语言一样将值强制为布尔值。
2021-05-01 18:36:01
不,但我认为 pointy 的意思是:var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.settings;. 如果 var 名称不长,实际上我更喜欢这种方式。但如果它们很长,我更喜欢你的方式,Rob。无论哪种方式,我都喜欢。+1
2021-05-01 18:36:01
请注意,这种方法对于深度嵌套的变量非常有用。当变量由两个名称组成时,例如foo.barmyVal = foo && foo.bar更方便。
2021-05-11 18:36:01

对不起,它不是很好:

var myVal = appData && appData.foo && appData.foo.bar && appData.foo.bar.setting;

另外一个选择:

try {
    var myVal = appData.foo.bar.setting;
} catch (e) {
    var myVal = undefined;
}

这 。运算符并不是真正用于访问这样的对象。使用函数可能是个好主意。

我发现其他方法有点巨大。那么,以下方法的主要缺点是什么:

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

基本上,我们在对象上定义一个方法(不一定),该方法获取嵌套对象的路径并返回存在确认,例如appData.pathExists("foo.bar.setting");

编辑:检查object[prop] == undefined在语义上不正确,因为即使定义了属性,它也会返回 false,尽管它的值为undefined; 这就是为什么我hasOwnProperty用来检查是否定义了属性。如果只需要获取值,这可能并不重要。

如果,之后:

var myVal = appData.foo && appData.foo.bar && appData.foo.bar.setting;

myVal不是undefined,它将持有appData.foo.bar.setting.

你可以试试这个

var x = {y:{z:{a:'b'}}}
x && x.y && x.y.z && x.y.z.a //returns 'b'

这不如 groovy 表达式好,但它有效。遇到第一个未定义的变量后,评估停止。