🤖
instanceof をごまかす
2つの方法を紹介します。
Object.setPrototypeOf
実際にはごまかすというよりは instanceof は MDN にあるとおり
instanceof 演算子は、あるコンストラクターの prototype プロパティが、あるオブジェクトのプロトタイプチェーンの中のどこかに現れるかどうかを検査します。
だけなので、納得感のある挙動なのですが、クラスベースの考え方だとあとから継承ツリーになにかを入れられるというのがやや違和感のある挙動なのでメモしておきます。
JavaScript には instanceof という二項演算子があります。左辺に値を、右辺にクラスを渡すと値がクラスのインスタンスかどうかを boolean で返してくれます。
class Foo {}
const foo = new Foo();
console.log(foo instanceof Foo); // true
instanceof 演算子は prototype に依存するので、Object.setPrototypeOf を使うことで挙動を変更できます。
次の例では obj はもともと Foo のインスタンスではないので、一回めの obj instanceof Foo は false を返します。しかし Object.setPrototypeOf(obj, foo); したあとの obj instanceof Foo は true を返します。
class Foo {}
const foo = new Foo();
const obj = {};
console.log(obj instanceof Foo); // false
Object.setPrototypeOf(obj, foo);
console.log(obj instanceof Foo); // true
Symbol.hasInstance
JavaScript には Symbol.hasInstance という Well-known Symbol があります。これを使うとクラスが instanceof 演算子の右のオペランドになったとき、どのように真偽値を返すかを制御できます。
class Foo {
static [Symbol.hasInstance]() {
return true;
}
}
const obj = {};
console.log(obj instanceof Foo); // true
Discussion