変数が定義済みかどうかの判定


たとえば、`data.value` が定義済みかどうかを判定するには

[code]

    if (typeof (data) !== 'undefined' && typeof (data.value) !== 'undefined') {
        console.log('defined:' + data.value);
    }
    
[/code]

という方法があると思いますが、もっと簡潔に記述する方法はないでしょうか？




質問内容が「変数が定義済みか」なのか「プロパティが定義済みか」なのか、判断に迷うところですが、両方の観点から回答します。

## TypeError

>
[code]

>     if (typeof (data) !== 'undefined' && typeof (data.value) !==
> 'undefined') {
>         console.log('defined:' + data.value);
>     }
>  
[/code]

こちらのコードは `data === null` の際に期待通りに動作しません。

[code]

    var data = null;
    typeof (data.value) !== 'undefined'; // TypeError: Cannot read property 'value' of null
[/code]

Null型、Undefined型にはプリミティブラッパーオブジェクトが存在せず、プロパティを持つことが出来ません。

## in 演算子

ご掲示のようなプロトタイプチェーンを含めてプロパティ存在判定を行う場合は **in演算子** を使いますが、
**プロパティを持てないUndefined型,Null型は例外** とします。

[code]

    'use strict';
    function hasProperty (object, propertyName) {
      return object != null && propertyName in Object(object);
    }
    
    console.log(hasProperty({a: 1}, 'a'));  // true
    console.log(hasProperty({a: undefined}, 'a'));  // true
    console.log(hasProperty('', 'split'));  // true
    console.log(hasProperty(Object.create(null), 'a')); // false
    console.log(hasProperty(null, 'a'));   // false
    console.log(hasProperty(undefined, 'a')); // false
    console.log(hasProperty(data, 'a')); // ReferenceError: data is not defined
[/code]

## ReferenceError

先のコードで分かるように、オブジェクトを格納した変数が未定義である場合は **ReferenceError** となってしまいます。  
`ReferenceError` を回避する為には `typeof` 演算子を使用する必要がありますが、`typeof`
演算子を関数化しても関数呼び出し時点で `ReferenceError` が発生してしまいます。  
未定義変数に対応するには、 **関数呼び出し前** に `typeof` 演算子を使用する必要があります。

[code]

    'use strict';
    function hasProperty (object, propertyName) {
      return object != null && propertyName in Object(object);
    }
    
    console.log(typeof data !== 'undefined' && hasProperty(data, 'a')); // false
[/code]

Re: jirolabo さん

