Область видимости, hoisting, типы
Где живёт имя, что успевает подняться и как плюс меняет типы.
var и let крепятся к разным местам. var принадлежит функции или всему скрипту, let и const — блоку: if, for или просто фигурным скобкам. Имя, объявленное внутри, затеняет внешнее, и снаружи внутреннее не видно. Но до своей строки внутреннее имя уже существует — именно поэтому обращение к нему не «берёт внешнее», а падает.
Подъём
function foo() {}поднимается целиком: её можно вызвать выше строки объявления.varподнимается только как объявление. До присваивания значениеundefined, а не ошибка.letиconstвходят в область, но до своей строки лежат в TDZ — временной мёртвой зоне. Чтение даётReferenceError.- Выражение не поднимается вообще.
const f = () => {}до своей строки — TDZ, а не функция.
Ловушка: typeof необъявленного имени возвращает "undefined" и не бросает, но имя в TDZ от typeof не спасает — будет ReferenceError.
Приведение типов
Оператор + перегружен. Если хотя бы одна сторона — строка, будет склейка, а не сложение: true + '1' даёт "true1". Остальные арифметические операторы всегда приводят к числу: '5' - 2 это 3, а '5' + 2 это "52".
Как операторы приводят объекты:
[] + [] // "" — обе стороны стали пустыми строками[] + {} // "[object Object]"[1, 2] + [3] // "1,23"+[] // 0Ложных значений ровно восемь: false, 0, -0, 0n, "", null, undefined, NaN. Всё остальное истинно, включая [] и {}.
== приводит типы, === — нет. Из-за шага приведения == не транзитивен:
0 == "" // true0 == "0" // true"" == "0" // falseСравнения <, >, <=, >= числовые, поэтому null == 0 ложно, а null >= 0 истинно: null приводится к 0. Отдельно: NaN не равен ничему, даже себе.
- 1.1var поднимается, let в TDZсейчас
- 1.2Два let с одним именем
- 1.3function declaration и var-функция
- 1.4Локальный var затеняет внешний
- 1.5typeof, плюс и нестрогое равенство
- 1.6typeof необъявленного и typeof в TDZ
- 1.7var не видит блок, let видит
- 1.8const и стрелка не поднимаются
- 1.9function и var с одним именем
- 1.10Присваивание без объявления
- 1.11Переменная цикла снаружи for
- 1.12var из невыполненного if
- 1.13Лексическая область, не место вызова
- 1.14const запрещает другое присваивание
- 1.15typeof от typeof и разные типы
- 1.16true, null и undefined в плюсе
- 1.17Строки в арифметике и унарный плюс
- 1.18== не транзитивно
- 1.19Массив в == и в плюсе
- 1.20Что truthy на самом деле
- 1.21NaN, Number.isNaN и isNaN
- 1.22let внутри case: со скобками и без
- 1.23delete: переменная против свойства
- 1.24Присваивание параметру: число и объект
- 1.25Дефолты в деструктуризации: undefined и null
- 1.26Object.is смотрит иначе, чем ===
- 1.270 и пустая строка: ?? против ||
Задачи из сборки