Разница между typeof и instanceof в JavaScript
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Оператор typeof
определяет примитивный тип данных переменной, например, 'number'
или 'string'
. В отличие от него, instanceof
проверяет свойство наследования, уточняет, создан ли объект с использованием конкретного прототипа или класса.
typeof 'hello' === 'string'; // true
new Date() instanceof Date; // true
Идентификация базовых типов при помощи typeof
Применение для определения встроенных типов
Оператор typeof
обычно используется для определения примитивных типов данных: 'number'
, 'string'
, 'boolean'
, 'undefined'
, 'object'
, 'symbol'
(начиная с ECMAScript 2015), а также 'function'
.
Особенностью typeof
является то, что с его помощью можно легко установить, задана ли переменная, что позволяет избежать ошибок при обращении к неопределённой переменной:
if (typeof myVar !== 'undefined') {
// myVar абсолютно безопасна
}
Особенности typeof
Eсли говорить о JavaScript, то у typeof
есть свои нюансы:
typeof null
возвращает'object'
— это всем известная ошибка языка.- Массивы изначально являются объектами, поэтому
typeof []
вернёт'object'
. typeof NaN
выдаёт'number'
, хотя NaN означает "не число" (Not-A-Number).
Для проверки функций, typeof
выступает весьма надёжным инструментом:
if (typeof callBack === 'function') {
// вызовем функцию! 📞
}
Подтверждение принадлежности к классу при помощи instanceof
Проверка собственных типов и прототипов
Когда возникает необходимость узнать, является ли объект экземпляром определённого прототипа или класса, на помощь приходит оператор instanceof
. Он удобен при работе с встроенными сложными типами или типами, определёнными самим пользователем:
function MyCustomType(name) {
this.name = name;
}
const myVar = new MyCustomType('MyVar');
console.log(myVar instanceof MyCustomType); // true
instanceof
анализирует всю цепочку прототипов, проверяя свойства на уровне каждого прототипа 🪜.
Осмотрительное использование instanceof
Важно помнить, что в разных выполнениях контекста результат работы instanceof
может быть некорректным (например, при работе с iframe в браузерах или при различных контекстах VM в Node.js), так как сравниваемые объекты могут быть созданы в отличающихся областях действия.
Для примитивов и соответствующих им объектов-обёрток instanceof
может помочь определить различия в реализации в разных браузерах:
console.log('hello' instanceof String); // false
console.log(new String('hello') instanceof String); // true — непоследовательность обнаружена!
Кроме того, instanceof
может быть использован для проверки переменной на равенство null
:
let nonExistent = null;
console.log(nonExistent instanceof Object); // false — нет, не объект 🤷♂️
Визуализация
Можно сказать, что typeof
и instanceof
работают как пропускной пункт и инспектор:
typeof
выполняет роль паспортного контроля: – Он маркирует переменную её примитивным типом. Подпись:"Ты принадлежишь этому примитивному типу!"
console.log(typeof "hello"); // "string"
console.log(typeof true); // "boolean"
console.log(typeof []); // "object"
instanceof
действует как генеалогический инспектор: – Он анализирует всю цепь наследования переменной. Инспектор:"Давай-ка рассмотреть твоё генеалогическое древо!"
console.log([] instanceof Array); // 👍 true (Потомок класса Array)
console.log(new Date() instanceof Date);// 👍 true (Прямой потомок семейства Date)
typeof
применяется для примитивных типов: чтобы узнать сущность типа.instanceof
используется для определения происхождения объекта: чтобы установить, был ли объект создан с помощью определённого конструктора.
Вам предстоит выбирать: маркер типа или проверку генеалогии — что подойдёт лучше в каждой конкретной ситуации?
Разные подходы и оптимизация производительности
Сочетание typeof
и instanceof
для волосистых проверок типов
Использование как typeof
, так и instanceof
поможет выполнять непоколебимые проверки типов, применимые для различных браузеров:
function isString(value) {
return typeof value === 'string' || value instanceof String;
}
Осторожность при изменении прототипов
Изменение прототипа объекта может влиять на результаты работы instanceof
и негативно сказаться на производительности. Вы должны избегать модификации стандартных прототипов для обеспечения наилучшей совместимости.
Производительность instanceof
Интересно, что instanceof
может оказаться быстрее в сравнении с другими операциями, так как он сравнивает не значения, а указатели на области в памяти, которые представлены в цепочке прототипов.