首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >未知任意深度的Javascript对象导致脚本停止执行

未知任意深度的Javascript对象导致脚本停止执行
EN

Stack Overflow用户
提问于 2013-03-14 12:05:09
回答 3查看 89关注 0票数 2

我可能会收到这样的JSON结构

代码语言:javascript
复制
foo: {}

或者我可能会喜欢这样:

代码语言:javascript
复制
foo: {bar: {baz: 1} }

当我像这样检查第一个数据结构是否存在时:

代码语言:javascript
复制
if ( data.foo.bar.baz ) { }

脚本将完全停止运行。我在浏览器上看不到任何javascript错误。它就会停下来。不管怎样,最好能做到以上几点,而不是:

代码语言:javascript
复制
if ( data.foo && data.foo.bar && data.foo.bar.baz ) { }

解决这个问题的最好方法是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-14 12:29:26

如果您试图捕获深度嵌套对象上所有可能的错误,那么您可以使用多个if条件:

代码语言:javascript
复制
 if (data && data.foo && data.foo.bar && data.foo.bar.baz ) { }

或者,如果失败不是预期的情况,您可以使用异常处理程序:

代码语言:javascript
复制
try {
    var item = data.foo.bar.baz;
    // operate on item
} catch(e) {
    // perform any actions when it failed
}

有时,使用单个异常处理程序保护代码块可以极大地简化错误处理。当异常触发时,异常的性能比if测试差,所以您应该记住这一点,但意外的失败通常是异常最擅长的处理方式,有时它们可以真正简化您的其余代码。

似乎有一些开发人员基本上从来不想编写异常代码,而是更喜欢使用大量的if测试,但他们存在于语言中,因为他们非常擅长帮助解决某些类型的问题。

票数 1
EN

Stack Overflow用户

发布于 2013-03-14 12:28:32

假设您不能影响您正在使用的JSON,那么您检查的方式几乎是唯一的方法。尽管我更喜欢检查!== undefined。这纯粹是我的编程习惯,因为我不喜欢用if (object)检查object的有效性。我总是将这一行等同于if(object === true),从布尔逻辑的角度来看,这并不是一回事。

代码语言:javascript
复制
if ( data.foo !== undefined && data.foo.bar !== undefined && data.foo.bar.baz !== undefined) { }

你也许可以不检查data.foo !== undefined,因为你说foo可能是一个空对象。

如果您的代码有很多这样的检查,您可以在收到JSON数据时预先进行一次检查,并填充任何缺少的对象:

代码语言:javascript
复制
if ( data.foo === undefined) data.foo = {};
if ( data.foo.bar === undefined) data.foo.bar = {};
if ( data.foo.bar.baz === undefined) data.foo.bar.baz = null;  // or skip this, I suppose...
票数 2
EN

Stack Overflow用户

发布于 2013-03-14 14:00:10

丑陋、令人讨厌、可怕的方式是使用evaltry..catch。更健壮的方法是使用typeof

代码语言:javascript
复制
if (typeof foo != 'undefined' && foo !== Null &&
   typeof foo.bar != 'undefined' && foo.bar !== Null && 
   ... 
) {
    // stuff
}

然而,只有当最终属性的值不是undefined时,它才能工作(即,当属性存在但具有未定义的值时,它将失败)。

您可以创建一个更精确的通用属性测试器来测试自己的属性:

代码语言:javascript
复制
function testChain(obj) {

    for (var i=1, iLen=arguments.length; i<iLen; i++) {

        if (obj.hasOwnProperty(arguments[i])) {
          obj = obj[arguments[i]];

        } else {
          return false;
        }
    }
    return true;
}

alert( testChain({a:{b:'b'}}, 'a', 'b') ); // true

但这不会检查继承的属性。要检查这些属性,可以使用propertyIsEnumerable,但这不会检查不可枚举的属性(例如,内置对象的本机方法)。

因此,实际上没有通用的解决方案,您只能针对特定情况量身定做一个。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15401006

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档