instanceof 演算子がリテラル値で false を返す理由

2024-04-07

JavaScript リテラルと instanceof 演算子

リテラル値とは、コード内で直接記述される値のことです。例えば、以下のコードは全てリテラル値です。

  • 文字列リテラル: "Hello, world!"
  • 数値リテラル: 123
  • ブール値リテラル: true
  • null リテラル: null
  • undefined リテラル: undefined

instanceof 演算子は、左側のオペランドが右側のオペランドのコンストラクタ関数によって生成されたかどうかを検査します。以下の例では、instanceoftrue を返します。

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 を使用すると、直感に反する結果になることがあります。以下の例では、instanceoffalse を返します。

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


JavaScript、Node.js、Express で発生するエラー "Error: Can't set headers after they are sent to the client" の原因と解決策

このエラーが発生する原因は、主に以下の2つです。ミッドルウェアの順番: レスポンス送信後に実行されるミッドルウェアでヘッダーを設定しようとしている。非同期処理: 非同期処理内でヘッダーを設定し、その処理が完了する前にレスポンスが送信されてしまう。...


配列探索の達人になるための JavaScript メソッドガイド:indexOf、find、filter、some メソッドを駆使せよ

概要JavaScript の indexOf メソッドは、オブジェクト配列内にある特定の要素が初めて出現するインデックスを返します。要素が見つからない場合は -1 を返します。このメソッドは、配列内の要素の検索と特定によく使用されます。構文...


React Reduxにおけるフェッチエラー処理のベストプラクティス

React Reduxにおいて、非同期処理によるフェッチエラーはアプリケーションの安定性とユーザー体験に悪影響を及ぼす可能性があります。そのため、適切なエラー処理を実装することが重要です。本記事では、React Reduxにおけるフェッチエラー処理のベストプラクティスについて、分かりやすく解説します。...


TypeScript 型とインターフェースの違いを理解する

型型は、変数や関数の値の制約を定義するために使用されます。プリミティブ型 (例: number、string、boolean)、ユニオン型、タプル型、ジェネリック型など、さまざまな型があります。型エイリアスを使用して、既存の型の別名を作成することもできます。...


Vue.js CLIプロジェクトで開発サーバーのポート番号を変更する方法

そこで今回は、Vue. js CLIプロジェクトでポート番号を変更する方法を、2つの方法に分けて詳しく解説します。方法1:vue. config. jsファイルを使用するプロジェクトルートディレクトリに移動します。vue. config. js ファイルが存在しない場合は、以下のコマンドで作成します。...