typeof

typeof 演算子は、未評価のオペランドの型を示す文字列を返します。

構文

typeof 演算子の後に、オペランドを続けて書きます。

typeof operand
typeof(operand)

引数

operand は、オブジェクトまたはプリミティブ型を表す式を返します。

解説

以下は typeof が返す事が出来る値 (文字列) の一覧表です。型とプリミティブの詳細については、JavaScript のデータ構造のページも参照してください。

返値
Undefined "undefined"
Null "object" (下記参照)
真偽値 "boolean"
数値 "number"
BigInt (ECMAScript 2020 の新機能) "bigint"
文字列 "string"
シンボル (ECMAScript 2015 の新機能) "symbol"
Function オブジェクト (implements [[Call]] in ECMA-262 terms) "function"
その他のオブジェクト "object"

メモ: ECMAScript 2019 およびそれ以前の実装では、呼び出し可能な非標準のオブジェクトに対して、typeof が任意の実装定義の文字列値を返すことを許可していました。

実際にこれを利用したブラウザーとして知られているのは、古い Internet Explorer だけです。(下記参照

基本的な使い方

// 数値
typeof 37 === 'number';
typeof 3.14 === 'number';
typeof(42) === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number';            // "Not-A-Number" であるにもかかわらず。
typeof Number('1') === 'number';    // Number は数値に型強制できない値を含めて、
typeof Number('shoe') === 'number'; // あらゆるものを数字に解析します。

typeof 42n === 'bigint';


// 文字列
typeof '' === 'string';
typeof 'bla' === 'string';
typeof `template literal` === 'string';
typeof '1' === 'string';        // 文字列内の数値は文字列型のままです。
typeof (typeof 1) === 'string'; // typeof は常に文字列を返します。
typeof String(1) === 'string';  // String は何でも文字列に変換するので、toString よりも安全です。


// 真偽値
typeof true === 'boolean';
typeof false === 'boolean';
typeof Boolean(1) === 'boolean'; // Boolean は、値が truthy か falsy かに基づいて変換します。

typeof !!(1) === 'boolean';      // ! (論理 NOT) 演算子 2 つの呼び出しは、Boolean() と同等です。


// シンボル
typeof Symbol() === 'symbol'
typeof Symbol('foo') === 'symbol'
typeof Symbol.iterator === 'symbol'


// Undefined
typeof undefined === 'undefined';
typeof declaredButUndefinedVariable === 'undefined';
typeof undeclaredVariable === 'undefined'; 


// オブジェクト
typeof {a: 1} === 'object';

// Array.isArray または Object.prototype.toString.call を使用て、
// 通常のオブジェクトと配列を区別します。
typeof [1, 2, 4] === 'object';

typeof new Date() === 'object';
typeof /regex/ === 'object'; // 過去の実装は正規表現を参照してください。


// 以下のようなものは、紛らわしく、危険で、無駄なものです。それらの使用を避けてください。
typeof new Boolean(true) === 'object'; 
typeof new Number(1) === 'object'; 
typeof new String('abc') === 'object';


// 関数
typeof function() {} === 'function';
typeof class C {} === 'function';
typeof Math.sin === 'function';

null 型

// JavaScript の初期からの実装に基づく
typeof null === 'object';

JavaScript の最初の実装では、JavaScript の値は型タグと値で表現されていました。オブジェクトの型タグは 0 で、null は NULL ポインター (ほとんどのプラットフォームで 0x00) として表されていました。その結果、null はタグの型として 0 を持っていたため、typeof の戻り値は "object" です。(リファレンス)

ECMAScript の修正案が (オプトインを使用して) 提案されましたが、却下されました。それは typeof null === 'null' という結果になるものでした。

new 演算子の使用

// Function コンストラクターを除くすべてのコンストラクター関数は、
// 常に typeof 'object' です
let str = new String('String');
let num = new Number(100);

typeof str; // 'object' を返す
typeof num; // 'object' を返す

let func = new Function();

typeof func; // 'function' を返す

構文で括弧が必要な場合

// 式のデータ型を特定するために、かっこを使用することができます。
let iData = 99;

typeof iData + ' Wisen'; // 'number Wisen'
typeof (iData + ' Wisen'); // 'string'

正規表現

呼び出し可能な正規表現は、一部のブラウザーでは非標準的な追加機能でした。

typeof /s/ === 'function'; // Chrome 1-12 ECMAScript5.1 に非準拠
typeof /s/ === 'object';   // Firefox 5+ ECMAScript 5.1 に準拠

エラー

ECMAScript 2015 より前では、typeof は常にそれが供給されたオペランドの文字列を返すことが保証されていました。宣言されていない識別子があっても、typeof'undefined' を返します。typeof を使用すると、エラーは発生しません。

しかしながら、ブロックスコープの letconst が追加されたことで、変数が宣言される前のブロック内で letconsttypeof を使用すると(またはクラスに typeof を使用すると)、ReferenceError が投げられます。ブロックスコープ内の変数は、ブロックの開始から初期化が処理されるまで「一時的なデッドゾーン」にあり、その間にアクセスされるとエラーを投げます。

typeof undeclaredVariable === 'undefined';

typeof newLetVariable; // ReferenceError
typeof newConstVariable; // ReferenceError
typeof newClass; // ReferenceError

let newLetVariable;
const newConstVariable = 'hello';
class newClass{};

例外

現在のブラウザーではすべて、標準外のホストオブジェクト document.allundefined 型になります。

typeof document.all === 'undefined';

仕様では、非標準のオブジェクトののためのカスタム型タグを許可していますが、それらの型タグは定義済みのものとは異なるものであることを要求しています。document.all'undefined' という型を持っている場合、ウェブ標準ではオリジナルの ECMA JavaScript 標準の "故意の違反" として分類されています。

実際の使い方

typeof は非常に便利ですが、汎用性はそれほど高くありません。たとえば、typeof([])typeof(new Date())typeof(/abc/) などと同様に 'object' です。

型のチェックをより具体的にするために、プロダクションレベルのコードで使用するための typeof ラッパーは以下のようになります。(obj が存在する場合)

  function type(obj, fullClass) {

    // obj の toPrototypeString() を取得します。(すべての型を処理します)
    // 初期の JS 環境では null の場合 '[object Object]' を返すので、直接確認するのがベストです。
    if (fullClass) { 
        return (obj === null) ? '[object Null]' : Object.prototype.toString.call(obj);
    }
    if (obj == null) { return (obj + '').toLowerCase(); } // 暗黙の toString() 変換

    var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
    if (deepType === 'generatorfunction') { return 'function' } 

    // 過剰な特異性を防いでください。(例えば、[object HTMLDivElement] など)
    // 機能的な正規表現 (Android <=2.3)、機能的な <object> 要素 (Chrome <=57, Firefox <=52) などを考慮します。
    // String.prototype.match は普遍的にサポートされています。

    return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType : 
       (typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj;
  }

存在しない変数をチェックすると、ReferenceError が投げられるため、typeof nonExistentVar === 'undefined' を使用します。

仕様

仕様書
ECMAScript (ECMA-262)
The typeof Operator の定義

ブラウザー実装状況

Update compatibility data on GitHub
デスクトップモバイルサーバー
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeAndroid 版 FirefoxAndroid 版 OperaiOSのSafariSamsung InternetNode.js
typeofChrome 完全対応 1Edge 完全対応 12Firefox 完全対応 1IE 完全対応 3Opera 完全対応 3Safari 完全対応 1WebView Android 完全対応 1Chrome Android 完全対応 18Firefox Android 完全対応 4Opera Android 完全対応 10.1Safari iOS 完全対応 1Samsung Internet Android 完全対応 1.0nodejs 完全対応 0.1.100

凡例

完全対応  
完全対応

IE 特有のメモ

IE 6、7、8 では、以下のように多くのホストオブジェクトがオブジェクト型であり、関数ではありません。

typeof alert === 'object'

一部の非標準 IE プロパティは他の値を返します。(tc39/ecma262#1440 (comment))

typeof window.external.AddSearchProvider === "unknown";
typeof window.external.IsSearchProviderInstalled === "unknown";

関連情報