instanceof
Baseline
åºãå©ç¨å¯è½
ãã®æ©è½ã¯åºãå®è£ ããã¦ãããå¤ãã®ãã¼ã¸ã§ã³ã®ç«¯æ«ããã©ã¦ã¶ã¼ã§åä½ãã¾ãã2015å¹´7æä»¥éããã¹ã¦ã®ãã©ã¦ã¶ã¼ã§å©ç¨å¯è½ã§ãã
instanceof æ¼ç®åã¯ãããã³ã³ã¹ãã©ã¯ã¿ã¼ã® prototype ããããã£ãããããªãã¸ã§ã¯ãã®ãããã¿ã¤ããã§ã¼ã³ã®ä¸ã®ã©ããã«ç¾ãããã©ãããæ¤æ»ãã¾ããè¿å¤ã¯è«çå¤ã§ãããã®åä½ã¯ Symbol.hasInstance ã§ã«ã¹ã¿ãã¤ãºãããã¨ãã§ãã¾ãã
試ãã¦ã¿ã¾ããã
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const auto = new Car("Honda", "Accord", 1998);
console.log(auto instanceof Car);
// äºæ³ãããçµæ: true
console.log(auto instanceof Object);
// äºæ³ãããçµæ: true
æ§æ
object instanceof constructor
弿°
object-
æ¤æ»ãããªãã¸ã§ã¯ãã§ãã
constructor-
æ¤æ»å¯¾è±¡ã®é¢æ°ã§ãã
ä¾å¤
TypeError-
constructorããªãã¸ã§ã¯ãã§ãªãå ´åãçºçãã¾ããconstructorã[Symbol.hasInstance]()ã¡ã½ãããæã£ã¦ããªãå ´åã¯ã颿°ã§ãªããã°ãªãã¾ããã
解説
instanceof æ¼ç®åã¯ã object ã®ãããã¿ã¤ããã§ã¼ã³ã« constructor.prototype ãåå¨ãããã¨ãæ¤æ»ãã¾ããããé常ï¼ãã ã常ã«ã§ã¯ãªãï¼ãobjectãconstructorã§æ§ç¯ãããã¨ãããã¨ãæå³ãã¦ãã¾ãã
// ã³ã³ã¹ãã©ã¯ã¿ã¼ãå®ç¾©
function C() {}
function D() {}
const o = new C();
// true : Object.getPrototypeOf(o) === C.prototype ã§ãããã
o instanceof C;
// false : D.prototype 㯠o ã®ãããã¿ã¤ããã§ã¼ã³ã®ã©ãã«ãåå¨ããªããã
o instanceof D;
o instanceof Object; // true : ãªããªã...
C.prototype instanceof Object; // true ã§ãããã
// `constructor.prototype` ãå代å
¥ã
// ãã®ãããªãã¨ã¯ããã£ãã«ãã¹ãã§ã¯ããã¾ããã
C.prototype = {};
const o2 = new C();
o2 instanceof C; // true
// false : C.prototype 㯠o ã®ãããã¿ã¤ããã§ã¼ã³ã®
// ã©ãã«ãåå¨ããªããã
o instanceof C;
D.prototype = new C(); // C ã D ã® [[Prototype]] ãªã³ã¯ã«è¿½å
const o3 = new D();
o3 instanceof D; // true
o3 instanceof C; // true : o3 ã®ãããã¿ã¤ããã§ã¼ã³ã« C.prototype ããããã
ãªãããªãã¸ã§ã¯ã使å¾ã« constructor.prototype ãå代å
¥ãããã¨ï¼éå¸¸ã¯æ¨å¥¨ããã¾ããï¼ãinstanceof æ¤æ»ã®å¤ãå¤åããå¯è½æ§ãããã¾ããã¾ããObject.setPrototypeOf ã使ç¨ã㦠object ã®ãããã¿ã¤ãã夿´ãããã¨ã§ããã®å¤ã夿´ãããã¨ãã§ãã¾ãã
ã¯ã©ã¹ãåæ§ã«åä½ããæ¹æ³ã§ããã¯ã©ã¹ã«ã prototype ããããã£ãåå¨ããããã§ãã
class A {}
class B extends A {}
const o1 = new A();
// true : Object.getPrototypeOf(o1) === A.prototype ã§ãããã
o1 instanceof A;
// false : B.prototype ã o1 ã®ãããã¿ã¤ããã§ã¼ã³å
ã«ãªã£ããã
o1 instanceof B;
const o2 = new B();
// true : Object.getPrototypeOf(Object.getPrototypeOf(o2)) === A.prototype ã§ãããã
o2 instanceof A;
// true : Object.getPrototypeOf(o2) === B.prototype ã§ãããã
o2 instanceof B;
ãã¤ã³ãæ¸ã¿é¢æ°ã«ã¤ãã¦ã¯ãinstanceof ã¯å¯¾è±¡ã¨ãã颿°ã® prototype ããããã£ãè¦ã¦ããã¾ããããã¯ããã¤ã³ãæ¸ã¿é¢æ°ã«ã¯ prototype ãåå¨ããªãããã§ãã
class Base {}
const BoundBase = Base.bind(null, 1, 2);
console.log(new Base() instanceof BoundBase); // true
instanceof 㨠Symbol.hasInstance
constructor ã Symbol.hasInstance ã¡ã½ãããæã¤å ´åããã®ã¡ã½ãããåªå
çã«å¼ã³åºããã弿°ã¨ã㦠object ã®ã¿ãåãåãã this ã¨ã㦠constructor ãæ¸¡ããã¾ãã
// ãã®ã¯ã©ã¹ã¯ãå
·ä½çãªãã©ã°ãããããã£ã¨ãã¦æã¤éãããã¬ã¼ã³ãªãã¸ã§ã¯ãã
// ãã®ã¯ã©ã¹ã®ã¤ã³ã¹ã¿ã³ã¹ã§ããããã«å½è£
ã§ããããã«ãã
class Forgeable {
static isInstanceFlag = Symbol("isInstanceFlag");
static [Symbol.hasInstance](obj) {
return Forgeable.isInstanceFlag in obj;
}
}
const obj = { [Forgeable.isInstanceFlag]: true };
console.log(obj instanceof Forgeable); // true
ãã¹ã¦ã®é¢æ°ã¯æ¢å®ã§ Function.prototype ãç¶æ¿ãããããå³è¾ºã颿°ã§ããå ´åãã»ã¨ãã©ã®å ´å㯠Function.prototype[Symbol.hasInstance]() ã¡ã½ããã instanceof ã®åä½ãæå®ãã¾ãã instanceof ã®æ£ç¢ºãªã¢ã«ã´ãªãºã ã«ã¤ãã¦ã¯ãSymbol.hasInstance ãã¼ã¸ãåç
§ãã¦ãã ããã
instanceof ã¨è¤æ°ã®é å
JavaScriptã®å®è¡ç°å¢ï¼ã¦ã£ã³ãã¦ããã¬ã¼ã ãªã©ï¼ã¯ãããããã®ç¬èªã®é åã«å±ãã¦ãã¾ããã¤ã¾ããçµã¿è¾¼ã¾ãã¦ãããã®ãå¤ããã¾ãï¼å¥ã
ãªã°ãã¼ãã«ãªãã¸ã§ã¯ããå¥ã
ãªã³ã³ã¹ãã©ã¯ã¿ã¼ããªã©ï¼ãããã«ããäºæãã¬çµæã«ãªãå ´åãããã¾ããä¾ãã°ã[] instanceof window.frames[0].Array 㯠false ãè¿ãã¾ãã Array.prototype !== window.frames[0].Array.prototype ã§ãããé
åã¯åè
ãç¶æ¿ãã¦ããããã§ãã
ããã¯ãå§ãã¯ãããã«ããããããã¾ããããã¹ã¯ãªããã§è¤æ°ã®ãã¬ã¼ã ãã¦ã£ã³ãã¦ãæ±ãããªãã¸ã§ã¯ããããã³ã³ããã¹ãããå¥ã®ã³ã³ããã¹ãã¸é¢æ°ãçµç±ãã¦æ¸¡ãããã«ãªãã¨ãæ£å½ãã¤éè¦ãªäºé
ã«ãªãã¾ããä¾ãã°ã Array.isArray() ã使ç¨ããã¨ãä¸ãããããªãã¸ã§ã¯ããå®éã«é
åã§ãããã©ãããå®å
¨ã«ãã§ãã¯ã§ãã¾ãã
ä¾ãã°ãå¥ã®ã³ã³ããã¹ãã§ãã Node ã SVGElement ã§ãããã©ããããã§ãã¯ããã«ã¯ãmyNode instanceof myNode.ownerDocument.defaultView.SVGElement ã使ç¨ãã¦ãã ããã
ä¾
>instanceof ã String ã«ä½¿ç¨
次ã®ä¾ã§ã¯ã instanceof ã String ãªãã¸ã§ã¯ãã«ä½¿ç¨ããå ´åã®åä½ã示ãã¦ãã¾ãã
const literalString = "ããã¯æååãªãã©ã«ã§ã";
const stringObject = new String("ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ä½æããã String ã§ã");
literalString instanceof String; // false : æååãªãã©ã«ã¯ String ã§ã¯ãªã
stringObject instanceof String; // true
literalString instanceof Object; // false : æååãªãã©ã«ã¯ Object ã§ã¯ãªã
stringObject instanceof Object; // true
stringObject instanceof Date; // false
instanceof ã Map ã«å¯¾ãã¦ä½¿ç¨
次ã®ä¾ã§ã¯ã instanceof ã Map ãªãã¸ã§ã¯ãã«ä½¿ç¨ããå ´åã®åä½ã示ãã¦ãã¾ãã
const myMap = new Map();
myMap instanceof Map; // true
myMap instanceof Object; // true
myMap instanceof String; // false
Object.create() ã§çæããããªãã¸ã§ã¯ã
次ã®ä¾ã§ã¯ã instanceof ã Object.create() ã§çæãããªãã¸ã§ã¯ãã«ä½¿ç¨ããå ´åã®åä½ã示ãã¦ãã¾ãã
function Shape() {}
function Rectangle() {
Shape.call(this); // ã¹ã¼ãã¼ã¯ã©ã¹ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ãå¼ã³åºã
}
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;
const rect = new Rectangle();
rect instanceof Object; // true
rect instanceof Shape; // true
rect instanceof Rectangle; // true
rect instanceof String; // false
const literalObject = {};
const nullObject = Object.create(null);
nullObject.name = "My object";
literalObject instanceof Object; // true : ãã¹ã¦ã®ãªãã¸ã§ã¯ããªãã©ã«ã¯ Object.prototype ããããã¿ã¤ãã¨ãã¦æã¤
({}) instanceof Object; // true : ä¸è¨ã¨åã
nullObject instanceof Object; // false : ãããã¿ã¤ãã¯ãããã¿ã¤ããã§ã¼ã³ã®æ«å°¾ (null)
myCar ã Car åããã³ Object åã§ãããã¨ã示ã
以ä¸ã®ã³ã¼ãã¯ãCar ãªãã¸ã§ã¯ãåã¨ãã®ã¤ã³ã¹ã¿ã³ã¹ã§ãã myCar ãçæãã¦ãã¾ããinstanceof æ¼ç®åã§ãmyCar 㯠Car åããã³ Object åã§ãããã¨ã示ãã¾ãã
function Car(make, model, year) {
this.make = make;
this.model = model;
this.year = year;
}
const myCar = new Car("Honda", "Accord", 1998);
const a = myCar instanceof Car; // true ãè¿ã
const b = myCar instanceof Object; // true ãè¿ã
instanceof ã®å¦å®
ãããªãã¸ã§ã¯ããç¹å®ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã® instanceof ã§ãªããã¨ãæ¤æ»ããã«ã¯ã次ã®ããã«ãã¾ãã
if (!(myCar instanceof Car)) {
// 次ã®ãããªãã¨ããã
// myCar = new Car(myCar)
}
ããã¯å®éã«ã¯æ¬¡ã®ãã®ã¨ã¯ç°ãªãã¾ãã
if (!myCar instanceof Car) {
// ããã«ã¯å°éããªã
}
ããã¯å¸¸ã« false ã«ãªãã¾ããï¼!myCar 㯠instanceof ã®åã«è©ä¾¡ãããããã常ã«è«çå¤ã Car ã®ã¤ã³ã¹ã¿ã³ã¹ã§ãããã©ãããæ¤æ»ãããã¨ãã¾ããï¼
instanceof ã®åä½ã®ãªã¼ãã¼ã©ã¤ã
instanceof ã使ç¨ããéã®ããããè½ã¨ãç©´ã¯ã x instanceof C ãçã®å ´åã x ã C ãã³ã³ã¹ãã©ã¯ã¿ã¼ã¨ãã¦ä½æãããã¨ä¿¡ãããã¨ã§ããããã¯çã§ã¯ããã¾ããããªããªãã x ã¯ãããã¿ã¤ãã¨ã㦠C.prototype ãç´æ¥å²ãå½ã¦ããã¦ä½æãããå¯è½æ§ãããããã§ãããã®å ´åãã³ã¼ãã x ãã C ã®ãã©ã¤ãã¼ããã£ã¼ã«ããèªã¿åããã¨ãã¦ã失æãã¾ãã
class C {
#value = "foo";
static getValue(x) {
return x.#value;
}
}
const x = { __proto__: C.prototype };
if (x instanceof C) {
console.log(C.getValue(x)); // TypeError: Cannot read private member #value from an object whose class did not declare it
}
ããé¿ããããã«ã C ã« Symbol.hasInstance ã¡ã½ããã追å ã㦠instanceof ã®åä½ã䏿¸ããããã¨ãã§ãã¾ããããã«ããã in ã使ã£ããã©ã³ããã§ãã¯ããããã¨ãã§ãã¾ãã
class C {
#value = "foo";
static [Symbol.hasInstance](x) {
return #value in x;
}
static getValue(x) {
return x.#value;
}
}
const x = { __proto__: C.prototype };
if (x instanceof C) {
// x 㯠C ã§ã¯ãªããããå®è¡ãããªã
console.log(C.getValue(x));
}
ãã®åä½ãç¾å¨ã®ã¯ã©ã¹ã«å¶é ãããããããã¾ãããããããªãã¨ããµãã¯ã©ã¹ã§èª¤æ¤ç¥ãçºçããå¯è½æ§ãããããã§ãã
class D extends C {}
console.log(new C() instanceof D); // true : D 㯠C ãã [Symbol.hasInstance] ãç¶æ¿ãã¦ãããã
ãããè¡ãã«ã¯ãthisãç¾å¨ã®ã³ã³ã¹ãã©ã¯ã¿ã¼ã§ãããã©ããã調ã¹ããã¨ãã§ãã¾ãã
class C {
#value = "foo";
static [Symbol.hasInstance](x) {
return this === C && #value in x;
}
}
class D extends C {}
console.log(new C() instanceof D); // false
console.log(new C() instanceof C); // true
console.log({ __proto__: C.prototype } instanceof C); // false
仿§æ¸
| 仿§æ¸ |
|---|
| ECMAScript® 2027 Language Specification > # sec-relational-operators > |