Почему instanceof возвращает false для некоторых литералов?
Быстрый ответ
Примитивные типы данных в JavaScript, такие как 1
или 'text'
, не являются объектами, и поэтому оператор instanceof
возвращает false. Этот оператор предназначен для проверки наследования от определенного объекта. Для работы с примитивными типами используйте оператор typeof
. Однако, вы можете создать объект-обёртку для примитивного типа с помощью соответствующего конструктора, тогда instanceof
вернет ожидаемый результат.
console.log(1 instanceof Number); // false – 1 не считает себя объектом
console.log(typeof 1 === 'number'); // true – 1 является числом
console.log('text' instanceof String); // false – текстовая строка не считает себя объектом
console.log(new String('text') instanceof String); // true – теперь текст является объектом (аналогия с Пиноккио)
Управление литералами, прототипами и проверкой типов в JavaScript
Разберем подробнее, как работают литералы, прототипы и оператор instanceof
в JavaScript.
Примитивные типы данных и их взаимодействие с typeof
Примитивные типы данных — это базовые типы данных в JavaScript (string
, number
, boolean
, null
, undefined
, symbol
, bigint
). Они не имеют структуры объекта и для их определения используется typeof
.
Роль объектных оберток в instanceof
Если требуется представить примитивный тип данных в виде объекта, используется ключевое слово new
с соответствующим конструктором (например, String
, Number
, Boolean
). Это позволяет создавать объект, который можно проверить с помощью instanceof
.
instanceof
и его работа с массивами, функциями
Массивы и функции являются объектами, поэтому они хорошо совместимы с оператором instanceof
:
console.log([] instanceof Array); // true – даже пустой массив остается массивом
console.log(function(){} instanceof Function); // true – каждая функция имеет свое предназначение (даже пустая)
null
и undefined
: особые случаи
null
и undefined
не связаны с какими-либо конструкторами объектов, поэтому instanceof
всегда возвращает false
при их использовании.
Определение внутренних типов с Object.prototype.toString
Иногда требуется точное определение типа объекта. В этом случае на помощь приходит метод Object.prototype.toString
, который выявляет внутренние свойства объекта, скрытые от typeof
:
console.log(Object.prototype.toString.call([])); // [object Array] – суть массива внутри
console.log(Object.prototype.toString.call(/regex/)); // [object RegExp] – суть регулярного выражения раскрыто
Визуализация
instanceof
можно визуализировать как проверку членства в "клубе объектов":
Литерал | instanceof Object | Простое объяснение |
---|---|---|
'hello' (строка) | 🚫 | 'hello' – не объект |
false (булево значение) | 🚫 | false – не объект |
42 (число) | 🚫 | 42 – не объект |
new String('hello') | ✅ | 'hello' – добро пожаловать в клуб объектов |
new Boolean(false) | ✅ | false – встречайте важного участника клуба |
new Number(42) | ✅ | 42 – вступил в клуб! |
Вывод: new
позволяет примитивным типам данных вступить в "клуб объектов". Без new
они остаются за его пределами, и instanceof
указывает на это.
Литерал | Статус |
---|---|
Без new | 🚶♂️❌🏛️ |
С new | 🚶♂️➡️🏛️ |
Заключение: new
выступает как членская карта для примитивных типов данных, чтобы они стали полноценными участниками "клуба объектов".
JavaScript: язык неожиданных возможностей
JavaScript сочетает в себе две стороны: гибкость форм и удивительные открытия. Развивая понимание его особенностей, вы делаете его удобным и функциональным инструментом.
Доверяйте, но проверяйте
Оператор instanceof
работает предсказуемо с примитивными типами данных, но всегда проверяйте информацию по официальной документации и другим авторитетным источникам.
Примитивы и объекты: две стороны одной медали
Примитивные типы данных сравниваются по значению и неизменны, в то время как объекты могут изменяться и сравниваются по ссылке. Это взаимоотношение иногда приводит к неожиданным ситуациям:
let str1 = 'text';
let str2 = new String('text');
console.log(str1 === str2); // false – одно и то же значение, но разные сущности
console.log(str1 == str2); // true – идентичное значение, но разные формы
Осторожно: примитивы в сравнении с объектами
Некорректное использование примитивных типов данных и объектов в JavaScript может привести к путанице:
let name = 'Jane';
name.last = 'Doe';
console.log(name.last); // undefined – 'Jane' не знает никакой 'last'
Полезные материалы
- instanceof – JavaScript | MDN – Энциклопедия операторов на MDN
- ECMAScript® 2024 Language Specification – Официальные выпуски со спецификацией
instanceof
в ECMAScript стандарте - Understanding the difference between Object.create() and new SomeFunction() – Stack Overflow – Обсуждение различий в создании объектов и применении
instanceof
- Class checking: "instanceof" – Детальное описание оператора
instanceof
со многими примерами - Why does instanceof return false for some literals? – Stack Overflow – Глубокий анализ вопроса о литералах и
instanceof