instanceof 演算子がリテラル値で false を返す理由
JavaScript リテラルと instanceof 演算子
リテラル値とは、コード内で直接記述される値のことです。例えば、以下のコードは全てリテラル値です。
- 文字列リテラル:
"Hello, world!"
- 数値リテラル:
123
- ブール値リテラル:
true
- null リテラル:
null
- undefined リテラル:
undefined
instanceof
演算子は、左側のオペランドが右側のオペランドのコンストラクタ関数によって生成されたかどうかを検査します。以下の例では、instanceof
は true
を返します。
const str = "Hello, world!";
console.log(str instanceof String); // true
const num = 123;
console.log(num instanceof Number); // true
const bool = true;
console.log(bool instanceof Boolean); // true
しかし、リテラル値に対して instanceof
を使用すると、直感に反する結果になることがあります。以下の例では、instanceof
は false
を返します。
console.log("Hello, world!" instanceof String); // false
console.log(123 instanceof Number); // false
console.log(true instanceof Boolean); // false
これは、リテラル値が直接コンストラクタ関数によって生成されるのではなく、プリミティブ型として JavaScript エンジンによって生成されるためです。
instanceof 演算子の代替手段
リテラル値の型を検査するには、typeof
演算子を使用することができます。typeof
演算子は、オペランドの型を表す文字列を返します。
console.log(typeof "Hello, world!"); // "string"
console.log(typeof 123); // "number"
console.log(typeof true); // "boolean"
instanceof
演算子は、オブジェクトが特定のコンストラクタ関数によって生成されたかどうかを検査するために使用されます。- リテラル値に対して
instanceof
を使用すると、直感に反する結果になることがあります。 - リテラル値の型を検査するには、
typeof
演算子を使用することができます。
補足
instanceof
演算子は、オブジェクトの型を検査するだけでなく、オブジェクトのプロトタイプチェーンを検査することもできます。typeof
演算子は、リテラル値だけでなく、変数やオブジェクトの型も検査することができます。
// 文字列リテラル
const str = "Hello, world!";
console.log(str instanceof String); // false
console.log(typeof str); // "string"
// 数値リテラル
const num = 123;
console.log(num instanceof Number); // false
console.log(typeof num); // "number"
// ブール値リテラル
const bool = true;
console.log(bool instanceof Boolean); // false
console.log(typeof bool); // "boolean"
// オブジェクトリテラル
const obj = {
name: "John Doe",
age: 30,
};
console.log(obj instanceof Object); // true
console.log(typeof obj); // "object"
// 配列リテラル
const arr = [1, 2, 3];
console.log(arr instanceof Array); // true
console.log(typeof arr); // "object"
// 関数リテラル
const func = function () {
console.log("Hello, world!");
};
console.log(func instanceof Function); // true
console.log(typeof func); // "function"
このコードを実行すると、以下の出力が得られます。
false
string
false
number
false
boolean
true
object
true
object
true
function
この出力から、instanceof
演算子はリテラル値に対して常に false
を返し、typeof
演算子を使用してリテラル値の型を検査できることがわかります。
例えば、以下のコードでは、obj
オブジェクトは Object
コンストラクタによって生成されていないにもかかわらず、instanceof
演算子は true
を返します。
const obj = new Date();
console.log(obj instanceof Object); // true
これは、Date
コンストラクタは Object
コンストラクタを継承しているためです。
リテラル値の型検査の他の方法
コンストラクタ関数のプロパティ
各コンストラクタ関数は、prototype
プロパティというプロパティを持っています。このプロパティは、そのコンストラクタ関数によって生成されるオブジェクトの原型となるオブジェクトです。
以下の例では、String
コンストラクタの prototype
プロパティを使用して、文字列リテラルかどうかを検査しています。
const str = "Hello, world!";
console.log(str.constructor === String); // true
クラス
JavaScript では、クラスを使用してオブジェクトを生成することができます。クラスには、constructor
メソッドというメソッドがあり、このメソッドはオブジェクト生成時に呼び出されます。
以下の例では、クラスを使用して、数値リテラルかどうかを検査しています。
class Number {
constructor(value) {
this.value = value;
}
}
const num = 123;
console.log(num instanceof Number); // true
型ガード
TypeScript では、型ガードを使用して、リテラル値の型を検査することができます。型ガードは、条件分岐を使用して、変数の型を絞り込むための仕組みです。
const str: string | number = "Hello, world!";
if (typeof str === "string") {
// str は文字列リテラル
} else {
// str は数値リテラル
}
instanceof
演算子とtypeof
演算子以外にも、リテラル値の型検査を行う方法はいくつかあります。- コンストラクタ関数の
prototype
プロパティを使用して、オブジェクトの型を検査することができます。 - クラスを使用して、オブジェクトの型を検査することができます。
- TypeScript では、型ガードを使用して、リテラル値の型を検査することができます。
- 簡単な検査であれば、
typeof
演算子を使用するのが最も簡単です。 - より複雑な検査を行う場合は、
instanceof
演算子やコンストラクタ関数のprototype
プロパティを使用することができます。 - TypeScript を使用している場合は、型ガードを使用するのが最も安全です。
javascript literals instanceof