

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

[code]

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

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


CC BY-SA 4.0
2019-05-22T11:10:18.487
55169
2019-05-26T01:55:37.673
3925
question
javascript typescript
変数が定義済みかどうかの判定


継承されたプロパティを除いてよいのであればhasOwnPropertyをつかってみてはどうでしょう

<https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty>


CC BY-SA 4.0
2019-05-22T12:32:12.163
55172
2019-05-22T12:32:12.163
5246
55169
answer


こんなかんじではいかがでしょうか？

[code]

    var data = {};
    
    function checkObject(){
      if (typeof (data) !== 'undefined' && typeof (data.value) !== 'undefined') {
          console.log('(Default)defined:' + data.value);
      }
      
      if ('value' in data) {
          console.log('(object in)defined:' + data.value);
      }
      
      if ( data.hasOwnProperty('value') ){
          console.log('(hasOwnProperty)defined:' + data.value);
      }
    }
    
    function setValue(){ data.value = 'test data'; }
    function clearValue(){ delete data.value; }
[/code]

[code]

    <button onclick="checkObject();">check</button><br />
    <button onclick="setValue();">set value</button><br />
    <button onclick="clearValue();">clear value</button>
[/code]


CC BY-SA 4.0
2019-05-23T05:00:53.187
55186
2019-05-23T05:00:53.187
7676
55169
answer


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

## 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 さん


CC BY-SA 4.0
2019-05-26T01:55:37.673
55250
2019-05-26T01:55:37.673
20262
55169
answer