【JavaScript】 typeof演算子は何を返しているのか?
更新日:2021/07/08
JavaScriptのtypeof演算子を使用すると、値の型チェックをおこなうことができます。
しかし少しクセが強い演算のため、わかりにくい面があります。
そこで今回は、typeof演算子について解説してみます。
typeof演算子とは
typeof演算子について、簡単に解説します。
typeof演算子は文字列を返す
typeof演算子は、値の型を文字列で返します。
例えば数値に対してtypeof演算を行うと、文字列"number"を返します。
文字列に対してtypeof演算を行うと、文字列"string"を返します。
typeof演算子の例
console.log( typeof 123 ); // "number"
console.log( typeof "abc" ); // "string"
typeof演算子による型チェック
typeof演算子が決まった文字列を返す特性を利用して、値の型チェックをおこなうことができます。
例えば変数が数値(Number型)のとき処理をおこないたいなら、次のようにコードを記述します。
変数が数値のとき処理をおこなう
const value = 123;
if( typeof value === "number" ) { /* 処理 */ }
文字列の比較なので、"Number"とか、"NUMBER"などではダメです。
わざわざ文字列比較しなければいけない点に迂遠な印象を受けますが、仕様なので仕方がありません。
構文として覚えておきましょう。
typeof演算子とオブジェクト
そしてオブジェクトに対してtypeof演算を行うと、文字列"object"を返します。
typeof演算子でオブジェクトを指定
console.log( typeof {} ); // "object"
しかし、関数(functionオブジェクト)は同じオブジェクトなのに、"function"を返します。
typeof演算子で関数を指定
console.log( typeof function(){} ); // "function"
console.log( typeof (()=>{}) ); // "function"
なんだか統一感がありませんし、他にも特例なものがありそうで少し使いにくく感じますね。
パターンは少ない
typeof演算子のアルゴリズムを確認してみると、次表に従って文字列を返しているだけということがわかります。。
typeof演算子のアルゴリズムはこちら
■12.5.5 typeof演算子(The typeof Operator)
値の型 | 返す値 |
---|---|
Undefined | "undefined" |
Null | "object" |
Boolean | "boolean" |
Number | "number" |
String | "string" |
Symbol | "symbol" |
BigInt | "bigint" |
関数以外のObject | "object" |
関数Object | "function" |
それほどパターンは多くないですね。
UndefinedとNull
通常UndefinedとNullのチェックは、typeof演算子を使用しません。
次のように値で直接確認できます。
UndefinedとNullのチェック
if( value === undefined ) { /* 処理 */ }
if( value === null ) { /* 処理 */ }
Object
オブジェクトで特例なのは、関数だけのようです。
しかし表をよく見ると、Nullのときも"object"を返しているのがわかります。
つまり、typeof演算子が"object"を返しても、オブジェクトと判断できないということです。
次のようにnullとの比較も必要です。
オブジェクトかどうかの確認
if( value !== null && typeof {} === "object" ) { /* 処理 */ }
オブジェクトとプリミティブ
上の表ではString型は、"string"と返すことになっています。
ここで勘違いしてはいけないのが、検査対象がプリミティブの時だけだということです。
JavaScriptにはStringオブジェクトというものがあります。
これとは、別だということです。
Stringオブジェクトはオブジェクトなので、typeof演算子は"object"を返します。
Stringオブジェクトは"object"を返す
console.log( typeof "abc" ); // "string"
console.log( typeof new String("abc") ); // "object"
BooleanオブジェクトとNumberオブジェクトも同じように、"object"を返します。
Stringオブジェクトは"object"を返す
console.log( typeof new Boolean(true);); // "object"
console.log( typeof new Number(123);); // "object"
なおSymbolとBigIntは、対応するオブジェクトをコード上で生成することができません。
生成されるのは、メソッドを実行するためにプリミティブ値が対応するオブジェクトに変換された時だけです。
そのため、上記のような比較は想定されません。
オブジェクトの種類の確認
型チェックに関連して、オブジェクトの種類を確認するケースが考えられます。
例えば、配列(Arrayオブジェクト)かどうかをチェックしたいときです。
この場合は、instanceof演算子を使用します。
配列かどうかの確認
const array = [];
console.log( array instanceof Array ); // true
JavaScript初心者のうちは、typeofかinstanceofか、どちらを使用すればいいのかわかりにくいです。
とりあえず、上の表に当てはまらないときは、instanceofを使用すると覚えておくといいです。
instanceofについては、こちら
■【JavaScript】 instanceof演算子とは?何を比較しているのか?
JavaScriptデータ型とtypeof演算子の不一致
JavaScriptの仕様では、全部で8つのデータ型が定義されています。
JavaScriptデータ型 | データ値 |
---|---|
Undefined型 | undefined値 |
Null型 | null値 |
Boolean型 | 真偽値(trueまたはfalse) |
String型 | 文字列値 |
Symbol型 | シンボル値 |
Number型 | 数値 |
BigInt型 | 長整数値 |
Object型 | オブジェクト値 |
typeofは値の型を返す演算子なので上記の表に沿った結果となるべきですが、少しアレンジが加えられています。
上の表に、typeof演算の結果を加えてみます。
JavaScriptデータ型 | データ値 | typeof演算結果 |
---|---|---|
Undefined型 | undefined値 | "undefined" |
Null型 | null値 | "object" |
Boolean型 | 真偽値(trueまたはfalse) | "boolean" |
String型 | 文字列値 | "string" |
Symbol型 | シンボル値 | "symbol" |
Number型 | 数値 | "number" |
BigInt型 | 長整数値 | "bigint" |
Object型 | オブジェクト値(関数以外) | "object" |
オブジェクト値(関数) | "function" |
赤文字が、本来のデータ型と異なる型名です。
これを見ると、typeof null の演算結果が "object" になるのは奇妙に感じますね。
理由を調べてみると、仕様作成時の記述間違い(仕様バグ)や、当時はオブジェクトの空参照にnullを使っていたので "object" を返すのは理にかなっているなど理由が挙げられていました。
しかしJavaScriptの仕様でtypeofの項目を読むと、typeofが何を目的とした演算子なのかが明記されていません。
書いてあるのはアルゴリズムだけです。
typeof演算子のアルゴリズムはこちら
■12.5.5 typeof演算子(The typeof Operator)
つまりtypeof演算子はデータの型を返しているのではなくて、対象となる値ごとに何らかの文字列を返しているだけと言えます。
深く考えずに、「そういうものなんだ」で納得しておけばいいという話かもしれませんね。
更新日:2021/07/08
関連記事
スポンサーリンク
記事の内容について
こんにちはけーちゃんです。
説明するのって難しいですね。
「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。
裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。
掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。
ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php
このサイトは、リンクフリーです。大歓迎です。