2016-07-12 9 views
2

私は例えばオブジェクトを持っている:プロパティの存在を確認する簡単な方法はありますか?

var extra = { 
    field1: { 
    foo: {}, 
    bar: {} 
    } 
} 

field1は私がextra.field1.fooの有無を確認する必要がある場合は、私が使用する必要があり、設定することが保証されていません。

if(typeof extra.field1 != 'undefined') { 
    if(typeof extra.field1.foo != 'undefined') { 
     .... 
    } 
} 

は、任意の簡素ありチェックを行う方法は?

答えて

3

Object.prototype.hasOwnProperty()と​​を使用できます。しかし、簡単にするために、あなたは、このような性質の存在を確認することができます。

if (extra.field1 && extra.field1.foo) { 
    // ... 
} 
+0

niceを使うことができます!私は代わりに例外を発生させると信じていました。 – rox

4

in演算子を使用できます。指定されたプロパティが指定されたオブジェクトである場合

inオペレータがtrueを返します。

if ('field1' in extra && 'foo' in extra.field1) { 
    // true for foo 
} 
+0

はい、これはtypeof' 'よりも簡単です。つまり、二重 '' if'チェックを避ける方法はありますか?書くのは面倒です。 – rox

+1

@rox '&&' – gcampbell

0

は、必ず両方のフィールドをチェックする必要がありますが、あなたはさまざまな方法でそれを書くことができます。あなたがオブジェクトをチェックしていることが確実な場合は、次のコードは、十分に安全次のようになります。

if (extra.field1) { //if field1 is not null/undefined/zero/empty string/false 
    if (extra.field.foo) {...} 
    ... 
} 

両方が「falsy」の値であるため、フィールド1は、0または空の文字列にすることができれば安全ではないことを

0

使用目的のhasOwnPropertyを(プロパ)このタスクのために。

if (extra.hasOwnProperty('field1') && extra.field1.hasOwnProperty('foo')) { 
    // ... 
} 
0

あなただけのオブジェクトが特定のプロパティを持っているかどうかを知りたい場合は、プロトタイプチェーン内に、あなたはin演算子使用することができますどんなに:

if (myprop in myobj) { 
    ... 
} 

は、彼の方法は、すべてをチェックすることを考えてみましょうあなたのオブジェクトが持つプロパティとメソッド、そしてそれが '言語'から得られるメソッド。 例として:

var o = { 
    "myprop": true 
}; 

if ("toString" in o) { 
    console.log('toString exists'); 
} 

それ 'のtoStringが存在する' プリントアウト。

あなただけのオブジェクトの内部チェックに興味があるなら、あなたは使用する必要があります:

if (Object.hasOwnProperty.call(myobject, myprop)) { 
    ... 
} 

これはtoStringhasOwnPropertyなどの継承されたメソッドを避けることができます。

汚い方法は!!方法を使用している:

if (!!myobject[myprop]) { 
    .... 
} 

このように力をブール値に任意myobject[myprop]に変換します。 この問題は、空文字列、nullまたはundefined、またはもちろんブール値falseのように、falseで変換できる値を持つことができる場合です。

1

配列(または文字列)をとり、その中の各要素をチェックする関数を作成すると、コード内に条件が1つしかないすべてのネストされたプロパティの存在を確認できます。

obj1 = { 
    field1: { 
    col1: 1, 
    col2: 'a' 
    } 
}; 
function checkExistence(arr) { 
    // if arr is a string convert it into an array before checking it 
    if (typeof arr == 'string') { 
    arr=arr.split('.'); 
    } 
    checked = arr[0]; i = 1; 
    checks = window.hasOwnProperty(checked); 
    while (checks && i < arr.length) { 
    checked+='.'+arr[i]; 
    checks = typeof eval(checked) != 'undefined'; 
    ++i; 
    } 
    if (!checks) console.log(checked+' is undefnied'); 
    else console.log(checked+' is defined'); 
    return checks; 
} 
checkExistence(['obj1','field1','col1']); 
// obj1.field1.col1 is defined 
checkExistence(['obj1','field1','col3']); 
// obj1.field1.col3 is undefnied 
checkExistence(['obj1','field2','col3']); 
// obj1.field2 is undefnied 
checkExistence(['obj2','field2','col3']); 
// obj2 is undefnied 
checkExistence('obj1.field1.col1'); 
// obj1.field1.col1 is defined 

... 

if (checkExistence('obj1.field2.value1')) { 
    // do something 
} 
1

この方法では、深度を無制限にチェックできます。

function exists(node, chainString) { 
 
    return chainString.split('.') 
 
    .every(prop => node && prop in node ? (node = node[prop]) || true : false); 
 
} 
 

 
nodes = [ 
 
    {x: { y: { z: 43 }}}, 
 
    {x: { y: { z: undefined }}}, 
 
    {x: { y: null }}, 
 
    {x: []}, 
 
]; 
 

 
console.log(nodes.map(n => exists(n, "x.y.z")));

+0

私はこのダイナミックなソリューションが好きです。一つの問題:あなたは 'node'を突然変異させ、オブジェクトは参照によって渡されるので、この突然変異は親スコープに影響します。ローカル変数を導入し、複製された配列をそれに割り当てます: 'let [... o] = node;'。次に、そのローカルvarを何の害もなく突然変異させることができます。 – ftor

+0

ああ、あなたは突然変異を行っていない、あなたは再割り当てを行う。申し訳ありませんが、私の前のコメントを無視してください。よくやった! 'exists'の名前を' lookup'で変更すると、私は完全に満足しています:D – ftor

+0

@ LUH3417なぜルックアップですか? 'Contains'、' exists'、または 'includes'が良い選択肢になります。 –

関連する問題