2

このような JSON 構造を受け取る場合があります

foo: {}

または私はこれが好きかもしれません:

foo: {bar: {baz: 1} }

次のように最初のデータ構造の存在を確認すると:

if ( data.foo.bar.baz ) { }

スクリプトは完全に実行を停止します。ブラウザなどで JavaScript エラーが表示されません。止まるだけです。いずれにせよ、次の代わりに上記を実行できると便利です。

if ( data.foo && data.foo.bar && data.foo.bar.baz ) { }

この問題に対処する最善の方法は何ですか?

4

3 に答える 3

2

消費しているJSONに影響を与えることができないと仮定すると、チェックしている方法がこれを行う唯一の方法です。私はチェックすることを好みますが!== undefinedif (object)の有効性をチェックすることを考えたくないので、これは純粋に私が持っているプログラミングの特異性ですobject。私は常にその行を と同一視していますがif(object === true)、これはブール論理の観点からは実際には同じではありません。

if ( data.foo !== undefined && data.foo.bar !== undefined && data.foo.bar.baz !== undefined) { }

data.foo !== undefinedfoo は空のオブジェクトである可能性があると言ったので、 をチェックしないで済むかもしれません。

コードにこれらのチェックが多数ある場合は、JSON データを受信する前に 1 つのチェックを行い、不足しているオブジェクトを埋めることができます。

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...
于 2013-03-14T04:28:32.047 に答える
1

深くネストされたオブジェクトで考えられるすべてのエラーをキャッチしようとしている場合は、複数のif条件を使用できます。

 if (data && data.foo && data.foo.bar && data.foo.bar.baz ) { }

または、失敗が予期された状態でない場合は、例外ハンドラーを使用できます。

try {
    var item = data.foo.bar.baz;
    // operate on item
} catch(e) {
    // perform any actions when it failed
}

1 つの例外ハンドラーでコード ブロックを保護すると、エラー処理が大幅に簡素化される場合があります。例外が発生すると、例外はテストよりもパフォーマンスが低下ifするため、そのことを覚えておく必要がありますが、多くの場合、予期しないエラーは例外の処理に最適であり、コードの残りの部分を本当に単純化できる場合があります。

一部の開発者は、基本的に例外を伴うコーディングをしたくifなく、代わりに多くのテストを使用することを好みますが、ある種の問題を支援するのに非常に優れているため、言語に存在します。

于 2013-03-14T04:29:25.917 に答える
0

醜い、厄介な、恐ろしい方法は、またはのいずれevalかを使用することtry..catchです。より堅牢な方法は、次を使用することtypeofです。

if (typeof foo != 'undefined' && foo !== Null &&
   typeof foo.bar != 'undefined' && foo.bar !== Null && 
   ... 
) {
    // stuff
}

ただし、最終的なプロパティが 以外の値を持つ場合にのみ機能しますundefined(つまり、プロパティが存在するが未定義の値を持つ場合は失敗します)。

より正確なジェネリック プロパティ テスターを作成して、独自のプロパティをテストできます。

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、列挙できないプロパティ (組み込みオブジェクトのネイティブ メソッドなど) はチェックされません。

したがって、実際には一般的な解決策はありません。特定のケースに合わせて調整することしかできません。

于 2013-03-14T06:00:09.710 に答える