04. instanceof Operator
Вызов obj instanceof Constructor
возвращает true
, если объект принадлежит классу Constructor
или классу, наследующему от него. Оператор instanceof
требует, чтобы левым операндом был объект, а правым – имя класса объектов. Результатом оператора будет значение true
, если объект, указанный слева, является экземпляром класса, указанного справа.
{} instanceof Object // => true
[] instanceof Array // => true
[] instanceof Object // => true
undefined instanceof Object // => false
null instanceof Object // => false
'abc' instanceof Object // => false
123 instanceof Object // => false
const d = new Date();
d instanceof Date; // => true
d instanceof Object; // => true
d instanceof Number; // => false
const a = [1, 2, 3];
a instanceof Array; // => true
a instanceof Object; // => true
a instanceof RegExp; // => false
Prototype chain and instanceof
instanceof
Проверка происходит через сравнение прототипов. Сама по себе функция-конструктор не участвует в процессе проверки! Важна только цепочка прототипов для проверяемого объекта.
Алгоритм проверки obj instanceof Constructor
:
Получить
obj.__proto__
Сравнить
obj.__proto__
сConstructor.prototype
Если не совпадает, тогда заменить
obj
наobj.__proto__
и повторить проверку на шаге 2 до тех пор, пока либо не найдется совпадение (результатtrue
), либо цепочка прототипов не закончится (результатfalse
).
Практически всегда для объектов выражение obj instanceof Object
вернет true
, поскольку объект имеет прототип Object.prototype
. Однако, если объект был создан без прототипа, то нельзя проверить его тип:
> Object.create(null) instanceof Object
false
> Object.prototype instanceof Object
false
Однако typeof
корректно распознает тип объекта:
> typeof Object.create(null)
'object'
> typeof Object.prototype
'object'
@@hasInstance
symbol
@@hasInstance
symbolA method with the key Symbol.hasInstance
lets an object C
customize the behavior of the instanceof
operator. Signature of that method [Symbol.hasInstance](potentialInstance : any)
.
obj instanceof Type
is equivalent to Type[Symbol.hasInstance](obj)
:
class Iterable {
static [Symbol.hasInstance](obj) {
return typeof obj[Symbol.iterator] === "function";
}
}
let array = [1, 5, 5];
let string = "Welcome";
let number = 15;
array instanceof Iterable; // => true
string instanceof Iterable; // => true
number instanceof Iterable; // => false
x instanceof C
works as follows in ES6:
If
C
is not an object, throw aTypeError
.If the method exists, call
C[Symbol.hasInstance](x)
, coerce the result toboolean
and return it.Otherwise, compute and return the result according to the traditional algorithm (
C
must be callable,C.prototype
in the prototype chain ofx
, etc.).
Особенности:
Позволяет делать собственные реализации проверки на
instanceof
Эта проверка может находится внутри объекта (а не функции-конструктора)
Пример: объекты относятся к одному классу, если у них есть атрибут foo
:
const obj = {
foo: true,
[Symbol.hasInstance](inst) {
return Boolean("foo" in this) === Boolean("foo" in inst);
}
};
const obj2 = {
foo: false
};
obj2 instanceof obj;
Last updated
Was this helpful?