Javascript как определить тип переменной
Перейти к содержимому

Javascript как определить тип переменной

  • автор:

typeof

The typeof operator returns a string indicating the type of the operand’s value.

Try it

Syntax

Parameters

An expression representing the object or primitive whose type is to be returned.

Description

The following table summarizes the possible return values of typeof . For more information about types and primitives, see also the JavaScript data structure page.

Type Result
Undefined «undefined»
Null «object» (reason)
Boolean «boolean»
Number «number»
BigInt «bigint»
String «string»
Symbol «symbol»
Function (implements [[Call]] in ECMA-262 terms; classes are functions as well) «function»
Any other object «object»

This list of values is exhaustive. No spec-compliant engines are reported to produce (or had historically produced) values other than those listed.

Examples

Basic usage

typeof null

In the first implementation of JavaScript, JavaScript values were represented as a type tag and a value. The type tag for objects was 0 . null was represented as the NULL pointer ( 0x00 in most platforms). Consequently, null had 0 as type tag, hence the typeof return value «object» . (reference)

A fix was proposed for ECMAScript (via an opt-in), but was rejected. It would have resulted in typeof null === «null» .

Using new operator

All constructor functions called with new will return non-primitives ( «object» or «function» ). Most return objects, with the notable exception being Function , which returns a function.

Need for parentheses in syntax

The typeof operator has higher precedence than binary operators like addition ( + ). Therefore, parentheses are needed to evaluate the type of an addition result.

Interaction with undeclared and uninitialized variables

typeof is generally always guaranteed to return a string for any operand it is supplied with. Even with undeclared identifiers, typeof will return «undefined» instead of throwing an error.

However, using typeof on lexical declarations ( let const , and class ) in the same block before the line of declaration will throw a ReferenceError . Block scoped variables are in a temporal dead zone from the start of the block until the initialization is processed, during which it will throw an error if accessed.

Exceptional behavior of document.all

All current browsers expose a non-standard host object document.all with type undefined .

Although document.all is also falsy and loosely equal to undefined , it is not undefined . The case of document.all having type «undefined» is classified in the web standards as a «willful violation» of the original ECMAScript standard for web compatibility.

Custom method that gets a more specific type

typeof is very useful, but it’s not as versatile as might be required. For example, typeof [] is «object» , as well as typeof new Date() , typeof /abc/ , etc.

For greater specificity in checking types, here we present a custom type(value) function, which mostly mimics the behavior of typeof , but for non-primitives (i.e. objects and functions), it returns a more granular type name where possible.

For checking potentially non-existent variables that would otherwise throw a ReferenceError , use typeof nonExistentVar === «undefined» because this behavior cannot be mimicked with custom code.

Типы данных

JavaScript является слабо типизированным или динамическим языком. Это значит, что вам не нужно определять тип переменной заранее. Тип определится автоматически во время выполнения программы. Также это значит, что вы можете использовать одну переменную для хранения данных различных типов:

Все типы данных в JavaScript, кроме объектов, являются иммутабельными (значения не могут быть модифицированы, а только перезаписаны новым полным значением)

Литералы#

Самое популярное определение: Литералы используются в тексте программы для обозначения числовых значений, строк, символов или логических констант. Другими словами литерал представляет собой постоянное значение, у которого нет имени.

В нашем случае понятие литерала немного отличное. Мы можем представить, что литерал это способ объявления значения какого-либо типа в коде.

Основные типы#

В JS 6 основных типов данных:

  1. Number (числа)
  2. String (строки)
  3. Boolean ( true / false )
  4. null
  5. undefined
  6. Object

Примитивы#

  • Числа ( Number )
  • Строки ( String )
  • Булевые значения ( Boolean )
  • Null ( Null )
  • Undefined ( Undefined )

Object и объектные типы#

  • Объекты ( Object )
  • Массивы ( Array )

Как узнать тип переменной или от чего она наследуется#

Про операторы касающиеся наследования мы будем говорить потом

Чтобы узнать тип переменной имеется оператор typeof

Для того чтобы узнать от какого типа наследуется значение, можно воспользоваться оператором instanceof ;

Пример, где мы использовали typeof

Приведение типов#

Приведение типов — это процесс преобразования значений из одного типа в другой (например — строки в число, объекта — в логическое значение, и так далее). Любой тип в JavaScript, идёт ли речь о примитивном типе, или об объекте, может быть преобразован в другой тип. Напомним, что примитивными типами данных в JS являются Number, String, Boolean, Null, Undefined.

Существует 3 варианта преобразования:

  • В String
  • В Number
  • В Boolean

И несколько правил того как это происходит:

Преобразование в String , когда вы используете оператор конкатенации строк.

Напомню, что у нас знак + отвечает за оператора: — Конкатенация строк — Арифметическое сложение

Вполне естественно, что оператор + считается оператором конкатенации, если один из операндов является строкой.

Как преобразовываются примитивы в String :

Преобразование типа к Boolean

По этому пункту есть интересный момент с тем, что неявное преобразование к Boolean , происходят фоном если мы используем конструкцию if/else или логические операторы || , && , ! .

Как преобразовываются примитивы в Boolean :

Преобразование к Number

Здесь правила более объемные, давайте по пунктам:

  • Операторы сравнения (>, <, <=, >=).
  • Побитовые операторы (|, &, ^,

Восемь типов данных, typeof

Материал на этой странице устарел, поэтому скрыт из оглавления сайта.

Более новая информация по этой теме находится на странице https://learn.javascript.ru/types.

В JavaScript существует несколько основных типов данных.

В этой главе мы получим о них общее представление, а позже, в соответствующих главах подробно познакомимся с использованием каждого типа в отдельности.

Число «number»

Единый тип число используется как для целых, так и для дробных чисел.

Существуют специальные числовые значения Infinity (бесконечность) и NaN (ошибка вычислений).

Например, бесконечность Infinity получается при делении на ноль:

Ошибка вычислений NaN будет результатом некорректной математической операции, например:

Эти значения формально принадлежат типу «число», хотя, конечно, числами в их обычном понимании не являются.

Особенности работы с числами в JavaScript разобраны в главе Числа.

Число «bigint»

В JavaScript тип «number» не может содержать числа больше, чем 2 53 (или меньше, чем -2 53 для отрицательных). Это техническое ограничение вызвано их внутренним представлением. 2 53 – это достаточно большое число, состоящее из 16 цифр, поэтому чаще всего проблем не возникает. Но иногда нам нужны действительно гигантские числа, например в криптографии или при использовании метки времени («timestamp») с микросекундами.

Тип BigInt был добавлен в JavaScript, чтобы дать возможность работать с целыми числами произвольной длины.

Чтобы создать значение типа BigInt , необходимо добавить n в конец числового литерала:

Более подробно тип данных BigInt мы рассмотрим в отдельной главе BigInt.

Строка «string»

В JavaScript одинарные и двойные кавычки равноправны. Можно использовать или те или другие.

В некоторых языках программирования есть специальный тип данных для одного символа. Например, в языке С это char . В JavaScript есть только тип «строка» string . Что, надо сказать, вполне удобно.

Более подробно со строками мы познакомимся в главе Строки.

Булевый (логический) тип «boolean»

У него всего два значения: true (истина) и false (ложь).

Как правило, такой тип используется для хранения значения типа да/нет, например:

О нём мы поговорим более подробно, когда будем обсуждать логические вычисления и условные операторы.

Специальное значение «null»

Значение null не относится ни к одному из типов выше, а образует свой отдельный тип, состоящий из единственного значения null :

В JavaScript null не является «ссылкой на несуществующий объект» или «нулевым указателем», как в некоторых других языках. Это просто специальное значение, которое имеет смысл «ничего» или «значение неизвестно».

В частности, код выше говорит о том, что возраст age неизвестен.

Специальное значение «undefined»

Значение undefined , как и null , образует свой собственный тип, состоящий из одного этого значения. Оно имеет смысл «значение не присвоено».

Если переменная объявлена, но в неё ничего не записано, то её значение как раз и есть undefined :

Разбираемся в проверке JavaScript-типов с помощью typeof

Sergey Ufocoder

Очень важный аспект любого языка программирования — это его система типов и типы данных в нем. Для строго типизированных языков программирования, например для таких как Java, переменные определяются конкретными типами, которые в свою очередь ограничивают значения переменных.

Несмотря на то, что JavaScript — это динамически типизированный язык программирования, существуют расширения над языком, которые поддерживают строгую типизацию, например TypeScript.

В JavaScript возможно иметь переменную, которая была определена как содержащая значение типа string , а несколько позже на пути своего жизненного цикла она становится ссылкой на значение типа object . Также случается, что JavaScript-движок неявно занимается приведением типов во время выполнения сценария. Проверка типов очень важна для написания предсказуемых JavaScript-программ.

Для проверки типов в JavaScript присутствует довольно простой оператор typeof

Однако позже мы с вами увидим, что использование этого оператора может ввести в заблуждение, об этом мы поговорим ниже.

Типы данных в JavaScript

Перед тем как начать рассматривать проверку типов с помощью оператора typeof важно взглянуть на существующие типы данных в JavaScript. Хотя в этой статье не рассматриваются подробные сведения о типах данных JavaScript, вы все равно сможете что-то почерпнуть по мере чтения статьи.

До ES6 в JavaScript присутствовало 6 типов данных. Но с появлением ES6-спецификации был добавлен тип данных Symbol . Ниже приведен список всех существующих типов данных:

  1. String
  2. Number
  3. Boolean (значения true and false)
  4. null (значение null)
  5. undefined (значение undefined)
  6. Symbol
  7. Object

Первые шесть типов данных относятся к примитивным типам. Все другие типы данных помимо вышеуказанных шести являются объектами и относятся к ссылочному типу. Объект — это не что иное, как коллекция свойств, представленная в виде пар ключ и значение.

Обратите внимание, что в указанном списке типов данных, null и undefined — это примитивные типы в JavaScript, которые содержат ровно одно значение.

Вы уже наверно начали задаваться вопросом, а как же массивы, функции, регулярные выражения и прочие вещи? Все это специальные виды объектов.

  • array — специальный вид объектов, который представляет собой упорядоченную коллекцию пронумерованных значений со специальным синтаксисом и характеристиками, что отличает работу с ним от работы с другими объектами
  • function — специальный вид объектов, содержащий исполняемый сценарий, который выполняется при вызове функции. Этот вид объектов также имеет специальный синтаксис и характеристики, отличающие работу с ним от работы с другими объектами

JavaScript содержит несколько конструкторов для создания и других различных объектов, например, таких как:

  • Date — для создания объектов даты
  • RegExp — для создания регулярных выражений
  • Error — для создания JavaScript ошибок

Проверка типов с использованием typeof

Синтаксис

Оператор typeof в JavaScript является унарным оператором (принимает только один операнд), который возвращает строковое значение типа операнда. Как и другие унарные операторы, он помещается перед его операндом, разделенный пробелом:

Однако существует альтернативный синтаксис, который позволяет использовать typeof похожим на вызов функции, через оборачивание операнда в круглые скобки. Это очень полезно при проверке типов возвращаемого значения из JavaScript-выражения:

Защита от ошибок

До спецификации ES6 оператор typeof всегда возвращал строку независимо от операнда, который использовал.

Для необъявленных идентификаторов функция typeof вернет “undefined” вместо того, чтобы выбросить исключение ReferenceError.

Однако в ES6, переменные объявленные c блочной областью видимости с помощью let и const будут возвращать ReferenceError , если они использовались с оператором typeof до того как были инициализированы. А все потому что:

Переменные, имеющие блочную область видимости остаются во временной мертвой зоне до момента инициализации:

Проверка типов

Следующий фрагмент кода демонстрирует проверку типов c использованием оператора typeof :

Обратите внимание на то, что все значения созданные с помощью ключевого слова new всегда имеют тип “object” . Исключением из этого является только конструктор Function .

Ниже представлена сводка результатов проверок типов:

Улучшенная проверка типов

Результаты определения типов в предыдущем разделе показали, что некоторые значения требуют дополнительных проверок. Например, оба значения null и [] будут иметь тип "object" , когда проверка типа сделана с помощью typeof оператора.

Дополнительные проверки могут быть сделаны при использовании некоторых других характеристик, например:

  • использование оператора instanceof
  • проверка свойства constructor для объекта
  • проверка класса с помощью метода объекта toString()

Проверка на null

Использование оператора typeof для проверки значения "null" , как вы уже заметили, не лучшая идея. Лучший способ проверить на значение "null" — это выполнить строгое сравнение с null , как показано в следующем фрагменте кода:

Очень важным здесь является использование оператора строгого сравнения. Следующий фрагмент кода иллюстрирует использования значения undefined :

Проверка на NaN

NaN является специальным значением получаемым в результате арифметических операций, когда нет определения как можно представить результат. Например (0 / 0) => NaN . Также когда совершена попытка преобразования нечислового значения, у которого отсутствует возможное численного представление, результатом преобразования будет NaN .

Любая арифметическая операция, включающая в выражение NaN, всегда определяется как NaN.

Если вы действительно хотите применить произвольное значения для любой арифметической операции, тогда убедитесь, что это значение не NaN.

Использование оператора typeof для проверки типа для NaN вернет значение “number” . Для проверки же на значение NaN вы можете использовать глобальную функцию isNaN() или даже предпочтительней будет использовать функцию Number.isNaN() , добавленную в ES6:

Значение NaN в JavaScript имеет отличительную особенность. Это единственное значение в JavaScript, которое при сравнении с каким-либо другим значением, включая NaN, не будет ему эквивалентно

Вы можете проверить на значение NaN следующим образом

Функция выше очень похожа на реализацию функции Number.isNaN() , добавленную в ES6, и следовательно, ее можно использовать в качестве полифила для сред выполнения, отличных от ES6, следующим образом:

В заключение вы можете усилить проверку с помощью Object.is() , добавленную в ES6 для проверки на значение NaN . Функция Object.is() позволяет проверить, что два переданных в нее значения это одно и то же значение:

Проверка для массивов

Использование проверки с помощью typeof для массива вернет “object” . Существует несколько путей для того, чтобы проверить является ли значение массивом, как показано в нижнем фрагменте кода:

Очень важным здесь является использование оператора строгого сравнения. Следующий фрагмент кода иллюстрирует использования значения undefined :

Общий подход к проверке типов

Как вы видели на примере массивов, метод Object.prototype.toString() может быть полезным при проверки типов объектов для любого значения в JavaScript.

Когда вызывается этот метод с помощью call() или apply() , он возвращает тип объекта в формате: [object Type] , где Type является типом объекта.

Рассмотрим следующий фрагмент кода:

Фрагмент кода ниже демонстрирует результаты проверки типов с использованием созданной функции type() :

Бонус: не все является объектами

Очень вероятно, что в какой-то момент вы могли столкнуться с этим утверждением:

“Все сущности в JavaScript являются объектами.” — Неправда

Это ошибочное утверждение и на самом деле это неправда. Не все в JavaScript является объектами. Примитивы не являются объектами.

Вы можете начать задаваться вопросом — почему же мы можем делать следующие операции над примитивами, если они не являются объектами?

  • ("Hello World!").length — получить свойство length для строк
  • ("Another String")[8] — получить символ строки по индексу 8
  • (53.12345).toFixed(2) — выполнить Number.prototype.toFixed() метод над числом

Причина, по которой мы можем достичь всего этого над примитивами, заключается в том, что JavaScript-движок неявно создает соответствующий объект-обертку для примитива и затем вызывает указанный метод или обращается к указанному свойству.

Когда значение было возвращено, объект-обертка отбрасывается и удаляется из памяти. Для операций, перечисленных ранее, JavaScript-движок неявно выполняет следующие действия:

Заключение

В этой статье вы получили крупицу информации того, что является системой типов в JavaScript и типами данных, а также то, как проверка типов может быть выполнена с помощью оператора typeof .

Также вы видели, как проверка типов с помощью оператора typeof может ввести в заблуждение. И, наконец, вы видели несколько способов реализации предсказуемой проверки типов для некоторых типов данных.

Если вы заинтересованы в получении дополнительной информации об операторе typeof в JavaScript, обратитесь к этой статье.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *