Глубокое понимание типов данных JavaScript

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

  • Разница между void 0, null и undefined
  • Является ли String.length истинной длиной?
  • Правильный способ сравнения чисел с плавающей запятой.
  • Преобразование типов в JavaScript
  • Проверка типов данных в JavaScript

Разница между void 0, null и undefined

неопределенный

Форма MDN:

undefined - это свойство глобального объекта. То есть это переменная в глобальной области видимости. Начальным значением undefined является примитивное значение undefined.

Глобальное свойство с именем undefined по умолчанию имеет значение undefined. Это свойство можно было изменять до ES5, когда оно было доступно только для чтения.

нулевой

Из MDN:

Значение null записывается с помощью литерала: null. null не является идентификатором свойства глобального объекта, в отличие от undefined. Вместо этого null обозначает отсутствие идентификации, указывая на то, что переменная не указывает ни на какой объект.

В отличие от undefined, он не назначается по умолчанию чему-либо в JavaScript. Вы можете только вручную установить значение null.

void ‹experssion›

Из MDN:

Оператор void часто используется просто для получения примитивного значения undefined, обычно с использованием «void(0)» (что эквивалентно «void 0»). В этих случаях можно использовать глобальную переменную undefined.

Вывод

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

Поэтому, чтобы избежать непреднамеренного вмешательства, мы рекомендуем использовать void 0 для получения значения undefined.

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

Также следует отметить, что null и undefined имеют одинаковое значение, но разные типы.

Является ли String.length истинной длиной?

UTF-16, строковый формат, используемый JavaScript, использует одну 16-битную кодовую единицу для представления наиболее распространенных символов, но требует использования двух кодовых единиц для менее часто используемых символов, поэтому это возможно для значения, возвращаемого length, charAt и charCodeAt не соответствуют фактическому количеству символов в строке. Специально для операций, которые работают с неанглийскими строками. Например, вы можете использовать следующий код для вычисления длины смешанной строки между китайским и английским языками. Эта функция часто используется в сценариях, где длина вводимых символов ограничена.

ECMAScript 2016 (изд. 7) установил максимальную длину 2^53 - 1 элементов. Ранее максимальная длина не указывалась. В Firefox строки имеют максимальную длину 2**30 - 2 (~ 1 ГБ). В версиях до Firefox 65 максимальная длина была 2**28 - 1 (~ 256 МБ).

Правильный способ сравнения чисел с плавающей запятой.

Вы знаете, что в JavaScript 0,1 + 0,2 не равно 0,3. Это типичный случай потери точности. Если вы хотите вычислить результат 0,1 + 0,2, компьютер сначала преобразует 0,1 и 0,2 в двоичное, затем сложит и, наконец, преобразует результат сложения в десятичное число. При обоих преобразованиях произойдет потеря точности. Следовательно, полученные результаты неточны.

Итак, правильный способ проверить равенство чисел с плавающей запятой - использовать Number.EPSILON

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

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

Преобразование строк в числа

Есть три способа преобразовать строки в числа: Number(), parseInt(), parseFloat().

Число (): преобразование числовых строк и пустых значений в числа. Если строка находится в правильном десятичном, двоичном, восьмеричном и шестнадцатеричном выражении и в правильном знаковом научном представлении, ее можно преобразовать в число. Если обработка не удалась, верните NaN.

parseInt ( строка [, основание] ): функция parseInt преобразует свой первый аргумент в строку, анализирует эту строку, а затем возвращает целое число или NaN.

Если не NaN, возвращаемое значение будет целым числом, которое является первым аргументом, принятым как число в указанном radix. (Например, radix из 10 преобразуется из десятичного числа, 8 преобразуется из восьмеричного, 16 из шестнадцатеричного и т. Д.)

parseFloat (строка): функция parseFloat() анализирует аргумент (при необходимости сначала преобразуя его в строку) и возвращает число с плавающей запятой.

В большинстве случаев Number() - лучший выбор, чем parseInt()и parseFloat(). Если вы используете parseInt(), рекомендуется в любое время передать второй параметр.

Преобразование чисел в строки

Есть также два способа преобразовать числа в строки toString() и String().

toString ( [radix] ): метод toString() возвращает строку, представляющую указанный объект Number.

String (): глобальный метод String() может преобразовывать числа в строки. Его можно использовать с любым типом чисел, литералов, переменных или выражений.

Примитивные объекты-оболочки

У объекта есть набор методов и свойств. Мы знаем, что у строк есть несколько служебных методов, таких как substr, indexOf и replace. Кроме того, у них также есть свойство length. Кажется очевидным, что строки тоже подобны объектам. Но строки не являются объектами, они не могут позволить вам определять собственные методы и свойства:

Это происходит из-за объектов оболочки в JavaScript. За исключением null и undefined, все примитивные значения, Number, String, Boolean, Symbol, имеют эквиваленты объекта, которые обернуть примитивные значения.

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

Избегайте объектов String, Number и Boolean. Они усложняют ваш код и замедляют скорость выполнения.

Объекты примитивного типа

В Спецификации языка ECMAScript указана функция ToPrimitive(input[,PreferredType]), которая реализует преобразование из объектов в примитивный тип.

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

Преобразование объектов в строки и числа выполняется в два этапа.

  1. Превратите объекты в примитивные значения с помощью ToPrimitive.
  2. Преобразуйте примитивные значения в строки или числа с помощью valueOf и toString

Если valueOf и toString не существуют или не возвращают примитивный тип, это вызовет исключение TypeError.

При преобразовании объектов в строки сначала вызывается метод toString, а затем valueOf; при преобразовании объектов в числа сначала вызывается valueOf, а затем toString.

После ES6 объекты могут отменять поведение по умолчанию ToPrimitive, определяя @@toPrimitive Symoblmethod.

Проверка типов данных в JavaScript

Существует четыре метода проверки типов данных в JavaScript: typeof, instanceof, constructor, Object.prototype.toString.call().

тип

Оператор typeof возвращает строку, указывающую тип неоцененного операнда. Результаты включают: number, boolean, string, symbol, object, undefined, function.

Однако есть два исключения между возвратом typeof и типами данных времени выполнения. Один из них - typeof null return object с типом данных времени выполнения Null, а другой - typeof (function(){}) return function, тип данных времени выполнения которого Object.

Поскольку результаты typeof несовместимы с типом среды выполнения, мы можем использовать typeof для проверки типа данных только тогда, когда мы точно знаем, что переменная находится в диапазоне number, boolean, string, symbol, undefined и function.

экземпляр

Оператор instanceof проверяет, появляется ли свойство prototype конструктора где-нибудь в цепочке прототипов объекта. Возвращаемое значение - логическое значение.

Оператор instanceof проверяет только наличие constructor.prototype в цепочке прототипов объекта. instanceof не может тестировать примитивные типы. Будет возвращено два результата: Когда primitive type instanceof primitive type ошибка исключения возврата; Когда primitive type instanceof reference type вернет false.

конструктор

Метод constructor - это специальный метод class для создания и инициализации объекта этого класса.

Метод constructor похож на метод instanceof, но он также может тестировать примитивные типы.

Недостаток constructor: он не может тестировать null и undefined, потому что в null и undefined нет свойства constructor. Поэтому мы редко используем constructor для проверки типов данных в реальных проектах.

Object.prototype.toString.call ()

Objec.prototype.toString.call() - это наиболее часто используемый метод определения типа данных. Он вернет [ojbect type], второе значение type - это тип object.

Резюме обнаружения типа данных

  1. Примитивные типы: number, boolean, string, symbol, undefined и function используют typeof для определения типа данных.
  2. null используйте Object.prototype.toString.call() и === для проверки типа.
  3. Object используйте instanceof для тестирования.
  4. Мы можем использовать Object.prototype.toString.call(), чтобы проверить прежде всего ситуации.

Вывод

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

Спасибо за чтение, можно ожидать лучшего будущего.