2012-03-08 4 views
7

が、私は通常、自分がこのような深いオブジェクトを扱う見つける JavaScriptで膨大なif文を使用せずに "未定義のプロパティ"のエラーを回避するにはどうすればよいですか?コード内</p> <pre><code>var x = { y: { z: { a:true } } } </code></pre> <p>そしてどこか::

if(x.y.z.a === true){ 
    //do something 
} 

そして、X、Yのいずれかが、zの変数が未定義の可能性があり、いくつかの例では

:あなたは

潜在的な解決策がある「が未定義のプロパティ*を読み取ることができません」になるだろう。その場合には

if(x && x.y && x.y.z && x.y.z.a === true){ 
    //do something 
} 

jsfiddle:http://jsfiddle.net/EcFLk/2/

しかし、いずれに簡単に/短い方法は何ですか?インラインソリューション(特別な機能を使用しない)は素晴らしいでしょう。ありがとう。

+0

最後の1つが最短のものです。より長い名前の場合は、 'var tmp = x; if(tmp =&tmp.verylongname)&&(tmp = tmp.evenlongernameblabla)&&(tmp = tmp.doyougetit)){...} '。 –

+0

この場合、特別な関数を使いたいと思うでしょう。 –

+0

@Jesseあなたは例を挙げることができますか? – Sherzod

答えて

9

いいえ、あなたはすでに正しい方法を見つけました。もちろん、try/catchブロックを使用してエラー後の処理を行うことができますが、x && x.y && x.y.z && x.y.z.aソリューションを使用します。

あなたは本当にそれが1または"hi"だときatrueとしないように厳密に等しい場合のみに条件が真である場合を除き、(あなたが=== trueは必要ありませんが、あなたの質問から、私はあなたがその既に知っていると思っています。)あなたは、このための機能を使用したくないと述べてきた、と私はちょうどフィットし、笑いのために、どちらか一方の必要性を感じていない


function ref(obj, names) { 
    var rv = obj, index; 
    if (names) { 
     for (index = 0; rv && index < names.length; ++index) { 
      rv = rv[names[index]]; 
     } 
    } 
    return rv; 
} 

使い方:

if (ref(x, ["y", "z", "a"]) === true) { 
    // do something 
} 

関数呼び出しがso cheap these daysです...

または交互:

function ref(obj) { 
    var rv = obj, index; 
    for (index = 1; rv && index < arguments.length; ++index) { 
     rv = rv[arguments[index]]; 
    } 
    return rv; 
} 

使用法:

if (ref(x, "y", "z", "a") === true) { 
    // do something 
} 

...しかし、ほとんどのJavaScriptエンジンで、その遅くなります(argumentsが遅くなる傾向があります)。しかし、再び、スピードが問題になるためには、ループで何千回も繰り返さなければなりません。

それとも

サイムが示唆するように、単一の変数(私は splitを避けたが、それは高価ではありません):

function ref(obj, path) { 
    var rv = obj, names = path.split("."), index; 
    for (index = 0; rv && index < names.length; ++index) { 
     rv = rv[names[index]]; 
    } 
    return rv; 
} 

使用法:

if (ref(x, "y.z.a") === true) { 
    // do something 
} 

Live example of all three | Live source

+0

はい、 "a"変数は単なる例に過ぎません。ありがとう – Sherzod

+0

私のアプローチは 'val(x、 'y.z.a')'(単一の文字列) –

+0

です@ imeVidas:うん、私は '分割 'を避けていましたが、それは高価ではないです。私が今朝起きたときに思いついたバグを修正しました。もしそれが哀れみではないなら、私は何が分かっているのか分かりません。 –

1

これは:P

if ($($($(x).prop('y')).prop('z')).prop('a')) { 
    // code 
} 

ライブデモを動作します:http://jsfiddle.net/Yw5th/

それは醜い模様だが、少なくとも、それはワンライナーだとプロパティ名を繰り返す必要がありません( x && x.y && x.y.z && ...とは異なります)。

+0

私は特に長い変数名があるのが好きです。唯一の欠点は、ブラケットには注意が必要です。 – Sherzod

関連する問題

 関連する問題