Function.prototype[@@hasInstance]()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Function インスタンスの [@@hasInstance]() メソッドは、コンストラクター関数がオブジェクトをそのコンストラクターのインスタンスの一つであると認識するかどうかを決定するデフォルトの手続きを定義します。これは、instanceof 演算子から呼ばれます。

構文

js
func[Symbol.hasInstance](value)

引数

value

判定を行うオブジェクトです。プリミティブ値に対しては常に false を返します。

返値

func.prototypevalue のプロトタイプチェーン内に存在する場合は true を返し、そうでない場合は false を返します。value がオブジェクトではないか、this が関数でない場合は、常に false を返します。thisバインド済み関数である場合は、value およびもとになったターゲット関数における instanceof 判定の結果を返します。

例外

TypeError

this がバインド済み関数ではなく、かつ this.prototype がオブジェクトではないとき投げられます。

説明

instanceof 演算子は、右辺の値に [@@hasInstance]() メソッドが存在する場合は、常にこのメソッドを呼びます。すべての関数はデフォルトで Function.prototype を継承しているので、それらはすべてこの [@@hasInstance]() メソッドを持ちます。そのため、ほとんどの場合、右辺が関数であれば Function.prototype[@@hasInstance] メソッドが instanceof の挙動を定義します。このメソッドは、instanceof 演算子のデフォルトの挙動 (constructor@@hasInstance を持たないときと同じアルゴリズム) を実装します。

ほとんどのメソッドと違い、Function.prototype[@@hasInstance]() プロパティは設定不可能で、書込不可能です。これは、バインド済み関数のもとになったターゲット関数を取得されるのを防ぐためのセキュリティ機能です。例として、この StackOverflow での回答を参照してください。

デフォルトの instanceof の挙動に戻す

このメソッドを直接呼ぶ必要が生じることはほとんどないでしょう。かわりに、このメソッドは instanceof 演算子から呼ばれます。以下の 2 種類の結果は通常等価であることを期待するべきです。

js
class Foo {}
const foo = new Foo();
console.log(foo instanceof Foo === Foo[Symbol.hasInstance](foo)); // true

デフォルトの instanceof の挙動を呼び出したいが、コンストラクターにオーバーライドされた [@@hasInstance]() メソッドがあるかわからないとき、このメソッドを使いたくなるかもしれません。

js
class Foo {
  static [Symbol.hasInstance](value) {
    // 独自の実装
    return false;
  }
}

const foo = new Foo();
console.log(foo instanceof Foo); // false
console.log(Function.prototype[Symbol.hasInstance].call(Foo, foo)); // true

仕様書

Specification
ECMAScript Language Specification
# sec-function.prototype-%symbol.hasinstance%

ブラウザーの互換性

BCD tables only load in the browser

関連情報