Найти в Дзене
Как там в IT?

Подготовка к собеседованию - JavaScript. Часть 1: Всё о типах данных и приведении

Первая статья из серии, в которой мы разбираем ключевые темы JavaScript, необходимые для успешного прохождения технического интервью. Сегодня говорим о фундаменте — типах данных. Когда вы идёте на собеседование по JavaScript, даже если позиция подразумевает работу с Node.js или фреймворками, интервьюер почти всегда начинает с основ. И одна из первых тем — типы данных. Почему? Потому что непонимание разницы между примитивами и объектами, особенностей преобразования и проверки типов приводит к трудноуловимым багам. А ещё это отличный способ проверить, насколько глубоко кандидат понимает язык. В этой статье мы разберём: Материал рассчитан на начинающих разработчиков и тех, кто хочет систематизировать знания перед интервью. Поехали! В JavaScript все данные делятся на две группы: примитивные (простые значения) и ссылочные (объекты). Примитивы неизменяемы. Вы не можете изменить, например, символ строки по индексу — операция вернёт новую строку, но исходная останется прежней. Всё, что не явля
Оглавление

Первая статья из серии, в которой мы разбираем ключевые темы JavaScript, необходимые для успешного прохождения технического интервью. Сегодня говорим о фундаменте — типах данных.

Введение

Когда вы идёте на собеседование по JavaScript, даже если позиция подразумевает работу с Node.js или фреймворками, интервьюер почти всегда начинает с основ. И одна из первых тем — типы данных. Почему? Потому что непонимание разницы между примитивами и объектами, особенностей преобразования и проверки типов приводит к трудноуловимым багам. А ещё это отличный способ проверить, насколько глубоко кандидат понимает язык.

В этой статье мы разберём:

  • Примитивные и ссылочные типы — в чём разница.
  • Как происходит преобразование типов (явное и неявное).
  • Чем отличается === от == и почему лучше всегда использовать строгое равенство.
  • Какие значения считаются «ложными» (falsy).
  • Как правильно проверить тип переменной.

Материал рассчитан на начинающих разработчиков и тех, кто хочет систематизировать знания перед интервью. Поехали!

1. Примитивы и объекты: в чём принципиальная разница?

В JavaScript все данные делятся на две группы: примитивные (простые значения) и ссылочные (объекты).

Примитивные типы (их семь)

  • number — числа (целые, дробные, Infinity, NaN)
  • string — строки
  • boolean — true / false
  • undefined — значение не присвоено
  • null — «ничего», пусто
  • symbol (ES6) — уникальный идентификатор
  • bigint (ES2020) — целые числа произвольной длины

Примитивы неизменяемы. Вы не можете изменить, например, символ строки по индексу — операция вернёт новую строку, но исходная останется прежней.

Ссылочные типы

Всё, что не является примитивом, — это объект. Сюда входят:

  • обычные объекты {}
  • массивы []
  • функции
  • даты new Date()
  • регулярные выражения /regex/
  • и многое другое

Главное отличие: примитивы хранятся и передаются «по значению», а объекты — «по ссылке».

Рассмотрим на примере:

-2

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

Упаковка примитивов (autoboxing)

Вы когда-нибудь задумывались, почему у примитивов есть методы? Например, 'hello'.toUpperCase(). Ведь строка — примитив, у которого не может быть свойств. Дело в том, что в момент вызова метода JavaScript временно оборачивает примитив в объект-обёртку (String, Number, Boolean), вызывает метод, а затем уничтожает эту обёртку. Это называется autoboxing.

-3

Специально создавать обёртки через new String('hello') не рекомендуется — это приводит к путанице с типами и может вызвать неожиданное поведение.

2. Преобразование типов (type coercion)

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

Явное преобразование

Мы сами указываем, во что хотим превратить значение:

  • В строку: String(value) или value.toString() (но последнее не сработает для null и undefined).
  • В число: Number(value), parseInt(value, radix), parseFloat(value).
  • В булево: Boolean(value) или двойное отрицание !!value.

Примеры:

-4

Неявное преобразование

Автоматически происходит:

  • В арифметических операциях (+, -, *, /, %).
  • При сравнениях (==, >, <, >=, <=).
  • В логических контекстах (if, while, &&, ||, !).

Правила преобразования

1. Строковое: если в операции + один из операндов строка, второй тоже преобразуется в строку.

-5

2. Численное: для операций -, *, /, %, унарного +, а также для сравнений (>, < и т.д.) значения преобразуются в числа.

-6

При этом:

  • true → 1, false → 0
  • null → 0
  • undefined NaN
  • Строка, не являющаяся числом, → NaN

3. Логическое: в условиях все значения приводятся к true или false.
Falsy значения (приводятся к false):

  • false
  • 0, -0
  • 0n (bigint ноль)
  • '' (пустая строка)
  • null
  • undefined
  • NaN
  • document.all (редкость)

Все остальные значения — truthy, включая пустые объекты {}, пустые массивы [], даже строку 'false'.

3. Строгое и нестрогое равенство: === vs ==

  • ===строгое равенство. Сравнивает значения без преобразования типов. Если типы разные — сразу false.
  • ==нестрогое равенство. При необходимости преобразует типы по описанным выше правилам.

Примеры:

-7

Правила == достаточно сложны и могут привести к неожиданностям, поэтому практически всегда рекомендуется использовать ===!==). Исключение — когда вы намеренно хотите допустить преобразование, но такие случаи редки и обычно лучше сделать явное приведение.

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

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

typeof – оператор

Возвращает строку с типом операнда.

-8

Плюсы: быстрый, работает для большинства примитивов.
Минусы: null определяется как "object" (это признано багом, но исправлять его не стали ради обратной совместимости). Массивы тоже "object", поэтому для детальной проверки объектов нужны другие методы.

instanceof – проверка принадлежности классу

Проверяет, есть ли конструктор в цепочке прототипов объекта.

-9

Минусы:

  • Не работает с примитивами (кроме случаев, когда они созданы через конструктор, например new Number(5), но так обычно не пишут).
  • Может дать неверный результат при работе с iframe (разные глобальные объекты).

Array.isArray() – проверка на массив

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

-10

Number.isNaN() – проверка на NaN

Глобальная isNaN() сначала преобразует аргумент в число, поэтому isNaN('строка') вернёт true. Number.isNaN() проверяет строго: значение должно быть именно NaN.

-11

Object.prototype.toString.call(value) – универсальный способ

Возвращает внутренний тег объекта в формате "[object Type]". Надёжно работает для любых значений.

-12

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

Заключение

Мы разобрали фундаментальную тему — типы данных в JavaScript. Теперь вы знаете:

  • чем примитивы отличаются от объектов;
  • как и когда происходит преобразование типов;
  • почему === безопаснее ==;
  • какие значения считаются falsy;
  • как правильно проверить тип переменной.

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

Подписывайтесь, чтобы не пропустить!

Вопросы для самопроверки:

  1. Какие типы данных в JavaScript являются примитивными?
  2. Что произойдёт, если сравнить null == undefined и null === undefined?
  3. Какие значения приводятся к false в логическом контексте?
  4. Почему typeof null возвращает "object"?
  5. Как надёжно проверить, является ли переменная массивом?