JavaScript Essentials

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

Здесь, я не буду углубляться в детали, вместо этого мы пробежимся по списку основных тем, с которыми вы со временем столкнётесь в JS. Я дам список ресурсов для обучения. Другими словами, лучше разобраться с этим сейчас, чем откладывать на потом.

Уровень подготовки

Для этой темы особой подготовки не нужно. Это основы любого языка, но в JavaScript всё немного запутанно.

Типы и структуры данных. Основы.

Далее мы будем использовать оператор typeof, чтобы разобраться с типами.

Есть ли типы в JS?

Кто-то может сказать, что JS не типизированный язык или что его типы нельзя назвать системными типами. От вас не требуется объявлять тип при создании переменной, как в других строго типизированных языках, например int x = 10. Я же (как и JS специалисты) заявляю, что в JS есть типы.

JS можно назвать и динамически типизированным и слабо типизированным.

Статическая типизация

JS не является статически типизированным языком, если только вы не используете такие инструменты как Typescript или Flow, которые компилируют в JS код. Мы коснёмся этой темы для примера.

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

int x = 5
string y = 'abc'

Динамическая типизация

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

var a = 1 // int
b = 'test' // string
// etc

Слабая типизация

Слабо типизированные языки допускают изменение типа. Например: 1 + '2' // '12' . JS видит, что вы пытаетесь сложить число и строку (недопустимая операция), в результате он преобразует число в строку и возвращает ‘12’.

Примитивы

Эти шесть типов задуманы как примитивы. Они не являются объектами и не имеют собственных методов. Все примитивы неизменны.

  • Boolean — true or false
  • Null — нет значения
  • Undefined — объявленная переменная, но без значения
  • Number — целочисленные, с плавающей точкой и т.д.
  • String —строка
  • Symbol — уникальное значение, которое не совпадает с другими

Всё остальное это объекты.

Основы примитивов

Объекты

Приведу несколько стандартных объектов. Обратите внимание, некоторые из них были в списке примитивов, не спутайте их. Эти ведут себя как конструкторы, например Boolean('a') // true .

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

Есть ещё множество объектов, вот некоторые из них:

  • Function
  • Boolean
  • Symbol
  • Error
  • Number
  • String
  • RegExp
  • Math
  • Set

Основы объектов

Так, где же здесь подвох?

Неразбериха начинается, когда отличающиеся типы смешиваются. JavaScript преобразует типы на своё усмотрение.

 

Далее, я расскажу о других непонятных моментах и хитростях.

Важные принципы

  • Все значения примитивов ― неизменны
  • Осторожно с приведением типов
  • Здесь нет места статической типизации т.е. int num = 5
  • Движок JavaScript сам определяет типы

Странности

В JavaScript много странностей. Подробней здесь: Wtf JS?

Почему Null это объект?

Документация причисляет Null к примитивам, тем не менее оператор typeof возвращает значение ‘object’ .

По сути, это баг, который не исправили, потому что существующий код перестанет работать. Этот баг присутствовал ещё с первой версии JavaScript, он пришёл из функции typeof в исходниках JS. Я покажу это с помощью псевдокода:

Псевдокод

Улавливаете? Они не проверили null

Подробней о причинах отказа исправлять баг, читайте здесь. А здесь, та часть исходника JS о которой я говорил.

Почему не number стало number?

typeof NaN // 'number' WTF!?

Если коротко, то NaN определён как числовой тип, но это не настоящее число. NaN ― это результат неких математических операций, который не может считаться числом.

Или ещё короче, потому что эксперты так сказали 🙂

Примитив не является объектом и не имеет собственных методов

Если примитивы не имеют методов, тогда почему работает 'abc'.length ?

Я не ошибся, так сказано в документации.

Примитивы — это данные (значения, типы данных), которые не являются объектами и не имеют методов. В JavaScript есть 6 примитивов: string, number, boolean, null, undefined, symbol (новые из ECMAScript 2015).

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

Вот пример:

Строка — это примитив

По факту, строки являются примитивами, как упоминалось в статье, а не полноценными объектами. JS понимает, когда вы пытаетесь применить метод на объект String и преобразует ваш примитив в строковый объект. Когда дело сделано, временный объект удаляется и всё становится на свои места.

конструктор строки

Tips and Tricks

Способы использовать типы в своих интересах.

Пользуйтесь этим с осторожностью. В большинстве случаев, используйте Number(str) parseInt(x) String(num) и т.д. Это на всякий случай, если вдруг встретите подобное в чужом коде, чтобы знать зачем этот код. Или если вы играете в Code golf ⛳️

преобразование типа, значение по умолчанию, короткое if

Перевод статьи CodeDraken : JavaScript Essentials: Types & Data Structures