Базовый CS с нуля
Примитивные типы
Ты теперь знаешь, что тип — это правило интерпретации битов. Следующий логичный вопрос: какие типы реально доступны в языке, который ты изучаешь?
В JavaScript и TypeScript каждое значение принадлежит одной из небольшого набора встроенных категорий. Простейшие члены категорий — те, что хранят один неделимый кусок данных, — называются примитивными типами. Они образуют дно иерархии типов: числа, текстовые символы, решения истина/ложь, «здесь ничего», «ещё не задано». Примитивное значение нельзя разложить на более мелкие типизированные части.
Этот урок проходит через каждый примитивный тип в JS/TS, привязывает каждый к его
представлению на уровне битов и вводит typeof — способ, которым среда выполнения
сообщает тебе, какое правило интерпретации она применяет к значению.
После этого урока ты сможешь назвать пять категорий примитивных типов, встречающихся в повседневном коде JS/TS,
описать, что каждая из них представляет на уровне битов, предсказать результат выражения
typeof для любого примитивного значения, и объяснить, что означают null и undefined как
два разных «отсутствия».
JavaScript и TypeScript определяют пять категорий примитивных значений, встречающихся в повседневном коде:
-
number— любое числовое значение: целые числа, дроби и специальные значения IEEE 754:Infinity,-InfinityиNaN. Внутри хранится как 64-битное число с двойной точностью по стандарту IEEE 754 (8 байт). Даже целые числа вроде42хранятся именно так — у JS нет отдельного целочисленного типа. -
string— последовательность кодовых точек Unicode. В движке V8 короткая строка может храниться как последовательность 16-битных кодовых единиц UTF-16 в смежной памяти. Строковое значение — не один байт; это структурированное значение с длиной и блоком символьных данных. -
boolean— ровно два значения:trueиfalse. На аппаратном уровне это соответствует концепции 1 бита (хотя движки обычно хранят его как тегированное слово, а не отдельный бит, из соображений выравнивания). Семантика: одно из двух взаимно исключающих состояний. -
null— намеренное отсутствие какого-либо значения. Программист пишетnull, чтобы сказать: «этот слот намеренно ничего не содержит». Существует ровно одно значение null. -
undefined— непреднамеренное или незаданное отсутствие значения. Объявленная, но ещё не присвоенная переменная содержитundefined. Существует ровно одно значение undefined.
Спецификация TC39 фактически определяет семь примитивных типов: пять перечисленных
выше, плюс symbol (добавлен в ES2015, для уникальных непрозрачных идентификаторов) и
bigint (добавлен в ES2020, для целых чисел больше Number.MAX_SAFE_INTEGER). Этот урок
охватывает пять типов, встречающихся в повседневном коде; symbol и bigint служат
специализированным задачам, с которыми ты познакомишься позже.
Оператор typeof — это способ, которым среда выполнения сообщает тип значения. Для
любого выражения typeof expr возвращает строку с именем типа. Для примитивов:
| Значение | Результат typeof |
|---|---|
42 | "number" |
"hello" | "string" |
true | "boolean" |
undefined | "undefined" |
null | "object" ← историческая особенность |
Случай с null — широко известная языковая особенность: typeof null возвращает
"object" из-за ошибки в оригинальной реализации JS, которую не удалось исправить из
соображений обратной совместимости. На практике: null является примитивом, а не
объектом.
1
// 1. number — 64-битный IEEE 754 double в памяти
2
const temperature = 36.6;
3
const count = 100;
4
const big = 9007199254740991; // Number.MAX_SAFE_INTEGER
5
6
console.log(typeof temperature); // "number"
7
console.log(typeof count); // "number"
8
console.log(typeof NaN); // "number" — NaN это числовой паттерн битов
9
10
// 2. string — последовательность кодовых точек Unicode
11
const greeting = "hello";
12
const empty = "";
13
14
console.log(typeof greeting); // "string"
15
console.log(greeting.length); // 5 — длина является частью структурированного значения
16
17
// 3. boolean — только true или false
18
const isReady = true;
19
const isOver = false;
20
21
console.log(typeof isReady); // "boolean"
22
23
// 4. null — намеренное отсутствие
24
const slot = null;
25
console.log(typeof slot); // "object" — историческая особенность, null ЯВЛЯЕТСЯ примитивом
26
console.log(slot === null); // true — проверяй на null через ===, а не typeof
27
28
// 5. undefined — незаданное / ещё-не-присвоенное
29
let future; // объявлена, но не присвоена
30
console.log(typeof future); // "undefined"
31
console.log(future === undefined);// true
- L2 number: хранит 36.6 как 64-битный IEEE 754 double (8 байт)
- L7 typeof возвращает строку с именем типа
- L8 NaN — специальный паттерн битов IEEE 754, тип по-прежнему 'number'
- L12 string: свойство length сообщает количество кодовых точек
- L17 boolean: ровно два значения, true и false
- L21 null: typeof возвращает 'object' — известная ошибка JS, не исправляемая для совместимости
- L22 Используй === null для определения null, а не typeof
- L26 undefined: переменная объявлена, но никогда не присваивалась
Наблюдай, как typeof реагирует на каждый вид значения. Мы трассируем небольшую
программу, которая присваивает пять переменных (по одной на каждый из пяти повседневных примитивных типов) и
выводит результат их typeof.
1
const n = 42;
2
const s = 'A';
3
const b = true;
4
const x = null;
5
let u;
6
console.log(typeof n, typeof s, typeof b, typeof x, typeof u);
Частая ошибка
null и undefined выглядят похоже, но означают разное. null — намеренный выбор
программиста: «Я явно говорю, что этот слот ничего не содержит». undefined —
автоматическое: «эта переменная объявлена, но никогда не получала значения, или это
свойство не существует». Рассматривай их как два разных состояния отсутствия. В строгом
режиме TypeScript компилятор отслеживает их отдельно — функция, которая может вернуть
null, отличается от функции, которая может вернуть undefined.
Сколько байт занимает число JS (IEEE 754 double) в памяти?
Что возвращает typeof 42? Введи ASCII-код первого символа строки-результата 'number', которая начинается с 'n'. ASCII 'n' = 110.
Переменная объявлена через let x; и никогда не присваивалась. Сколько символов в строке 'undefined', которую возвращает typeof x?
Сколько различных булевых значений существует в JS? (true и false.)
Что возвращает typeof null? Введи длину строки-результата. Строка — 'object'. Сколько в ней символов?
Что корректно описывает, что возвращает typeof null, и почему?
JavaScript и TypeScript определяют пять примитивных типов, встречающихся в повседневном
коде: number (64-битный IEEE 754 double), string (последовательность Unicode),
boolean (true или false), null (намеренное отсутствие) и undefined
(неинициализированное или отсутствующее). (Полная спецификация добавляет symbol и
bigint, доводя общее число до семи — они рассматриваются, когда возникает
необходимость.) Каждый примитив представляет конкретное правило интерпретации,
применяемое к битам, которые хранит среда выполнения. Оператор typeof возвращает
имя этого правила в виде строки — с одной исторической особенностью: typeof null
возвращает "object", а не "null". Примитивные значения неделимы: из 42 нельзя
прочитать подполе так, как из объекта читают свойство. Они — атомарные строительные
блоки, из которых состоят все значения в JS/TS.