データの型が何であるかを知ることは、コードをエラーなくスムーズに動かすために、しばしばとても重要です。
JavaScriptには、値やオブジェクトの型を調べる方法がいくつかあります。
JavaScriptの型チェックの仕組みは、やや信頼性に欠けることがあります。
より良い型安全性とより強い型を求めるなら、TypeScriptを使うことをおすすめします。TypeScriptはJavaScriptを基にした言語で、静的型付け言語の型構文を備えています。
typeof演算子typeof演算子は、そのオペランドの型を返します。
出力は、"null"を除いて、プリミティブデータ型のいずれかの名前と一致する文字列です。
また、"function"や"object"になることもあります。
typeof undefined;
// => "undefined"
typeof true;
// => "boolean"
typeof 42;
// => "number"
typeof 'Hello, World!';
// => "string"
typeof function () {
return 'Hello, World';
};
// => "function"
typeof [1, 2, 3, 4];
// => "object"
typeof { city: 'Stockholm', country: 'Sweden' };
// => "object"
これは[歴史的な理由][typeof null is "object"]によるものです。
instanceof演算子オブジェクトの型を調べるには、instanceof演算子を使うことができます。
これは、2番目のオペランドが1番目のオペランドのプロトタイプチェーンに含まれるかどうかに応じて、booleanに評価されます。
もう少し説明すると、instanceofは、1番目のオペランドが2番目のオペランド、またはその子クラスのインスタンスかどうかを返します。
instanceofはオブジェクトに対してのみ機能します。
class Beverage {
// ...
}
// The Coffee class is a child of the Beverage class.
class Coffee extends Beverage {
// ...
}
const java = new Coffee();
java instanceof Coffee;
// => true
java instanceof Beverage;
// => true
Arrayクラスには、引数が配列かどうかを調べるArray.isArray()というメソッドがあります。
ウェブページのiframeなど、別のレルムで作られた配列に対してはinstanceof Arrayは機能しませんが、Array.isArray()なら機能します。
これは、Arrayクラスがレルムごとに異なるコンストラクターを持ち、各iframeが独自のレルムを持つためです。その結果、プロトタイプチェーン内の関数が異なるものになり、instanceof Arrayが失敗します。
Array.isArray()はこれを無視できるので、可能なときは常に使うべきです。
また、オブジェクトが実際にはArrayではなく、プロトタイプチェーンにArrayを持っているだけという誤検知も避けられます。
({ __proto__: Array.prototype }) instanceof Array
// => true
Array.isArray({ __proto__: Array.prototype })
// => false
in演算子in演算子は、1番目のオペランドが2番目のオペランドのプロパティかどうかを返します。
プロパティに値が定義されているかどうかは調べません。
undefinedに設定されたプロパティも、inは検出します。
class Coffee {
constructor() {
this.temperature = 'hot';
this.isDarkMatter = undefined;
}
coolDown() {
this.temperature = 'warm';
}
}
const espresso = new Coffee();
'temperature' in espresso;
// => true
'color' in espresso;
// => false
'isDarkMatter' in espresso;
// => true
inは、継承されたプロパティやメソッドに対してもtrueを返します。
"coolDown" in espresso
// => true
"constructor" in espresso
// => true
これを避けるには、代わりにObject.hasOwn()を使います。
Object.hasOwn()関数Object.hasOwn()メソッドは、指定したオブジェクトが_指定されたプロパティを自身で持っているかどうか_(継承されたものでもメソッドでもない)を返します。
class Coffee {
constructor() {
this.temperature = 'hot';
}
coolDown() {
this.temperature = 'warm';
}
}
const cappuccino = new Coffee();
Object.hasOwn(cappucino, 'temperature');
// => true
Object.hasOwn(cappucino, 'constructor');
// => false
Object.hasOwn(cappucino, 'coolDown');
// => false