检查 JavaScript 中深层嵌套对象属性是否存在的最简单方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6927242/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 22:22:08  来源:igfitidea点击:

What's the simplest approach to check existence of deeply-nested object property in JavaScript?

javascriptproperties

提问by Morgan Cheng

I have to check deeply-nested object property such as YAHOO.Foo.Bar.xyz.

我必须检查深层嵌套的对象属性,例如YAHOO.Foo.Bar.xyz

The code I'm currently using is

我目前使用的代码是

if (YAHOO && YAHOO.Foo && YAHOO.Foo.Bar && YAHOO.Foo.Bar.xyz) {
    // operate on YAHOO.Foo.Bar.xyz
}

This works, but looks clumsy.

这有效,但看起来很笨拙。

Is there any better way to check such deeply nested property?

有没有更好的方法来检查这种深度嵌套的属性?

采纳答案by jfriend00

If you expect YAHOO.Foo.Barto be a valid object, but want to make your code bulletproof just in case it isn't, then it can be cleanest to just put a try catch around it and let one error handler catch any missing segment. Then, you can just use one ifcondition instead of four that will detect if the terminal property exists and a catch handler to catch things if the intermediate objects don't exist:

如果您希望YAHOO.Foo.Bar成为一个有效的对象,但又想让您的代码防弹以防万一,那么在它周围放置一个 try catch 并让一个错误处理程序捕获任何丢失的段可能是最干净的。然后,您可以只使用一个if条件而不是四个条件来检测终端属性是否存在,如果中间对象不存在,则可以使用一个捕获处理程序来捕获事物:

try {
    if (YAHOO.Foo.Bar.xyz) {
        // operate on YAHOO.Foo.Bar.xyz
} catch(e) {
    // handle error here
}

or, depending upon how your code works, it might even just be this:

或者,根据您的代码的工作方式,它甚至可能是这样的:

try {
    // operate on YAHOO.Foo.Bar.xyz
} catch(e) {
    // do whatever you want to do when YAHOO.Foo.Bar.xyz doesn't exist
}

I particularly use these when dealing with foreign input that is supposed to be of a particular format, but invalid input is a possibility that I want to catch and handle myself rather than just letting an exception propagate upwards.

在处理应该具有特定格式的外部输入时,我特别使用这些,但无效输入是我想要捕获和处理自己而不是让异常向上传播的可能性。

In general, some javascript developers under-use try/catch. I find that I can sometimes replace 5-10 if statements checking input with a single try/catch around a larger function block and make the code a lot simpler and more readable at the same time. Obviously, when this is appropriate depends upon the particular code, but it's definitely worth considering.

通常,一些 javascript 开发人员未充分利用 try/catch。我发现有时我可以用一个更大的功能块周围的单个 try/catch 替换 5-10 个检查输入的 if 语句,同时使代码更简单,更易读。显然,什么时候合适取决于特定的代码,但这绝对值得考虑。

FYI, if the usual operation is to not throw an exception with the try/catch, it can be a lot faster than a bunch of if statements too.

仅供参考,如果通常的操作是不使用 try/catch 抛出异常,那么它也可能比一堆 if 语句快得多。



If you don't want to use the exception handler, you can create a function to test any arbitrary path for you:

如果您不想使用异常处理程序,您可以创建一个函数来为您测试任意路径:

function checkPath(base, path) {
    var current = base;
    var components = path.split(".");
    for (var i = 0; i < components.length; i++) {
        if ((typeof current !== "object") || (!current.hasOwnProperty(components[i]))) {
            return false;
        }
        current = current[components[i]];
    }
    return true;
}

Example usage:

用法示例:

var a = {b: {c: {d: 5}}};
if (checkPath(a, "b.c.d")) {
    // a.b.c.d exists and can be safely accessed
}

回答by Kernel James

var _ = {};

var x = ((YAHOO.Foo || _).Bar || _).xyz;

回答by ?ime Vidas

Consider this utility function:

考虑这个效用函数:

function defined(ref, strNames) {
    var name;
    var arrNames = strNames.split('.');

    while (name = arrNames.shift()) {        
        if (!ref.hasOwnProperty(name)) return false;
        ref = ref[name];
    } 

    return true;
}

Usage:

用法:

if (defined(YAHOO, 'Foo.Bar.xyz')) {
    // operate on YAHOO.Foo.Bar.xyz
}

Live demo:http://jsfiddle.net/DWefK/5/

现场演示:http : //jsfiddle.net/DWefK/5/

回答by Matt

If you need to check the correctness of the path, rather than the existance of the "xyz" member on the "YAHOO.Foo.Bar" object, it will probably be easiest to wrap the call in a try catch:

如果您需要检查路径的正确性,而不是“YAHOO.Foo.Bar”对象上“xyz”成员的存在,那么将调用包装在 try catch 中可能是最简单的:

var xyz;
try {
    xyz = YAHOO.Foo.Bar.xyz;
} catch (e) {
    // fail;
};

Alternately, you can do some string-kong-fu-magicTM:

或者,您可以执行一些 string-kong-fu-magic TM

function checkExists (key, obj) {
    obj = obj || window;
    key = key.split(".");

    if (typeof obj !== "object") {
        return false;
    }

    while (key.length && (obj = obj[key.shift()]) && typeof obj == "object" && obj !== null) ;

    return (!key.length && typeof obj !== "undefined");
}

The use as follows:

使用方法如下:

if (checkExists("YAHOO.Foo.Bar.xyz")) {
    // Woo!
};

回答by Albert Wu

This problem is solved quite beautifully by coffeescript (which compiles down to javascript):

这个问题被 coffeescript(它编译成 javascript)很好地解决了:

if YAHOO.Foo?.Bar?.xyz
  // operate on YAHOO.Foo.Bar.xyz

回答by jAndy

I actually voted to close the question as duplicate of javascript convert dotnotation string into objects.

我实际上投票结束了这个问题,因为javascript 的副本将点符号字符串转换为对象

However, I guess it's a different topic, but the answer there might still be helpful if you don't want to try-catchall the time.

但是,我想这是一个不同的主题,但是如果您不想一直这样做,那里的答案可能仍然有用try-catch

回答by qw3n

use a try catch.

使用try catch.

a={
  b:{}
};

//a.b.c.d?true:false; Errors and stops the program.

try{
  a.b.c.d;
}
catch(e){
  console.log(e);//Log the error
  console.log(a.b);//This will run
}