Примечание
ЭТО АРХИВНАЯ ВЕРСИЯ КУРСА!
Материалы предназначаются для пересдающих дисциплину "ОП.04 - Основы алгоритмизации и программирования" в соответствии с учебными планами СПО годов набора ДО 2023-го.
Материалы были перенесены со старого сайта с минимальной доработкой, поэтому не все возможности курса могут работать как ожидается, где-то может слететь форматирование.
Домашние задания в рамках курса проверяться не будут!
ОП.04 - 09 - Типы данных. Простые и специальные. Преобразование типов
Код примера для практической работы
Типы данных
Значения, которые мы можем присвоить переменной в любом языке программирования всегда относится к данным определённого типа. Например, это может быть строка или число.
Переменная в JavaScript может содержать любые данные. В один момент там может быть строка, а в другой — число:
// Не будет ошибкой
let message = "hello";
message = 123456;
Языки программирования, в которых такое возможно, называются «динамически типизированными». Это значит, что типы данных есть, но переменные не привязаны ни к одному из них.
[!INFO]
Не все языки позволяют присваивать разные типы данных одной переменной в процессе выполнения программы, как правило то как ведет себя язык зависит от того как реализована в нем т.н. «типизация». JavaScript — язык со слабой динамической типизацией, поэтому в процессе выполнения программы мы можем легко менять значения переменных не задумываясь об их типах.
В JavaScript существует восемь основных типов данных.
Число
let n = 123;
console.log(n);
n = 12.345;
console.log(n);
Числовой тип данных (number) представляет как целочисленные значения, так и числа с плавающей точкой.
Существует множество операций для чисел, например, умножение *, деление /, сложение +, вычитание - и так далее.
Кроме обычных чисел, существуют так называемые «специальные числовые значения», которые относятся к этому типу данных: Infinity, -Infinity и NaN.
Infinityпредставляет собой математическую бесконечность∞. Это особое значение, которое больше любого числа. Мы можем получить его в результате деления на ноль:console.log( 1 / 0 ); // Infinityили задать явно:
console.log( Infinity ); // InfinityNaNозначает вычислительную ошибку. Это результат неправильной или неопределённой математической операции, например:console.log( "не число" / 2 ); // NaN, такое деление является ошибкойЗначение
NaN«прилипчиво». Любая математическая операция сNaNвозвращаетNaN:console.log( NaN + 1 ); // NaN console.log( 3 * NaN ); // NaN console.log( "не число" / 2 - 1 ); // NaNЕсли где-то в математическом выражении есть
NaN, то оно распространяется на весь результат (есть только одно исключение:NaN ** 0равно1).
Специальные числовые значения относятся к типу «число».
BigInt (Большое число)
В JavaScript тип number не может безопасно работать с числами, большими, чем (т. е. 9007199254740991) или меньшими, чем для отрицательных чисел.
Для большинства случаев достаточно безопасного диапазона чисел от до . Но иногда нам нужен диапазон действительно гигантских целых чисел без каких-либо ограничений или пропущенных значений внутри него. Например, в криптографии или при использовании метки времени с микросекундами.
Тип BigInt был добавлен в JavaScript, чтобы дать возможность работать с целыми числами произвольной длины.
Чтобы создать значение типа BigInt, необходимо добавить n в конец числового значения:
// символ "n" в конце означает, что это BigInt
const someReallyBigNumber = 1234567890123456789012345678901234567890n;
console.log(someReallyBigNumber);
Строка
Строка (string) в JavaScript должна быть заключена в кавычки.
let str = "Привет";
console.log(str);
let str2 = 'Одинарные кавычки тоже подойдут';
console.log(str2);
let phrase = `Обратные кавычки позволяют встраивать переменные ${str}`;
console.log(phrase);
В JavaScript существует три типа кавычек.
- Двойные кавычки:
"Привет". - Одинарные кавычки:
'Привет'. - Обратные кавычки:
`Привет`.
Двойные или одинарные кавычки являются «простыми», между ними нет разницы в JavaScript.
Обратные же кавычки имеют расширенную функциональность. Они позволяют нам встраивать выражения в строку, заключая их в ${…}. Например:
let name = "Иван";
// Вставим переменную
console.log( `Привет, ${name}!` ); // Привет, Иван!
// Вставим выражение
console.log( `результат: ${1 + 2}` ); // результат: 3
Выражение внутри ${…} вычисляется, и его результат становится частью строки. Мы можем положить туда всё, что угодно: переменную name, или выражение 1 + 2, или что-то более сложное.
Обратите внимание, что это можно делать только в обратных кавычках. Другие кавычки не имеют такой функциональности встраивания!
Булев (логический) тип
Булев (иногда Булевый) тип (boolean) может принимать только два значения: true (истина) и false (ложь).
Такой тип, как правило, используется для хранения значений да/нет: true значит «да, правильно», а false значит «нет, не правильно».
Например:
let nameFieldChecked = true; // да, поле отмечено
console.log( nameFieldChecked );
let ageFieldChecked = false; // нет, поле не отмечено
console.log( ageFieldChecked );
Булевые значения также могут быть результатом сравнений:
let isGreater = 4 > 1;
console.log( isGreater ); // true (результатом сравнения будет "да")
Значение «null»
Специальное значение null не относится ни к одному из типов, описанных выше.
Оно формирует отдельный тип, который содержит только значение null:
let age = null;
console.log( age );
В JavaScript null не является «ссылкой на несуществующий объект» или «нулевым указателем», как в некоторых других языках.
Это просто специальное значение, которое представляет собой «ничего», «пусто» или «значение неизвестно».
В приведённом выше коде указано, что значение переменной age неизвестно.
Значение «undefined»
Специальное значение undefined также стоит особняком. Оно формирует тип из самого себя так же, как и null.
Оно означает, что «значение не было присвоено».
Если переменная объявлена, но ей не присвоено никакого значения, то её значением будет undefined:
let age;
console.log( age ); // выведет "undefined"
Технически мы можем присвоить значение undefined любой переменной:
let age = 123;
// изменяем значение на undefined
age = undefined;
console.log( age ); // "undefined"
…Но так делать не рекомендуется. Обычно null используется для присвоения переменной «пустого» или «неизвестного» значения, а undefined — для проверок, была ли переменная назначена.
Объекты и символы
Тип object (объект) — особенный.
Все остальные типы называются «примитивными», потому что их значениями могут быть только простые значения (будь то строка, или число, или что-то ещё). В объектах же хранят коллекции данных или более сложные структуры.
Объекты занимают важное место в языке и требуют особого внимания. Мы разберёмся с ними в рамках курса после того, как узнаем больше о примитивах.
Тип symbol (символ) используется для создания уникальных идентификаторов в объектах. Мы упоминаем здесь о нём для полноты картины, изучим этот тип после объектов.
Оператор typeof
Оператор typeof возвращает тип аргумента. Это полезно, когда мы хотим обрабатывать значения различных типов по-разному или просто хотим сделать проверку.
У него есть две синтаксические формы:
- Синтаксис оператора:
typeof x. - Синтаксис функции:
typeof(x).
Другими словами, он работает со скобками или без скобок. Результат одинаковый.
Вызов typeof x возвращает строку с именем типа:
console.log( typeof undefined ); // "undefined"
console.log( typeof 0 ); // "number"
console.log( typeof 1.23 ); // "number"
console.log( typeof 10n ); // "bigint"
console.log( typeof true ); // "boolean"
console.log( typeof "Привет!" ); // "string"
console.log( typeof Symbol("id") ); // "symbol"
console.log( typeof Math ); // "object" (1)
console.log( typeof null ); // "object" (2)
console.log( typeof alert ); // "function" (3)
Последние три строки нуждаются в пояснении:
Math— это встроенный объект, который предоставляет математические операции и константы. Мы рассмотрим его подробнее в главе Числа. Здесь он служит лишь примером объекта.- Результатом вызова
typeof nullявляетсяobject. Это официально признанная ошибка вtypeof, ведущая начало с времён создания JavaScript и сохранённая для совместимости. Конечно,nullне является объектом. Это специальное значение с отдельным типом. Почему так получилось? - Вызов
typeof alertвозвращаетfunction, потому чтоalertявляется функцией. Мы изучим функции дальше, где заодно увидим, что в JavaScript нет специального типа «функция». Функции относятся к объектному типу. Ноtypeofобрабатывает их особым образом, возвращаяfunction. Так тоже повелось от создания JavaScript. Формально это неверно, но может быть удобным на практике.
Преобразование типов
Чаще всего операторы и функции автоматически приводят переданные им значения к нужному типу.
Преобразование бывает явным и неявным. В случае явного преобразования, как правило, программист осознанно использует определенную функцию преобразования данных в нужный тип, в то время как неявное преобразование происходит по некоторой заранее предусмотренной в языке логике. Как правило, неявное преобразование свойственно динамическим языкам со слабой типизацией, к которым как раз и относится JavaScript.
Существует 3 наиболее широко используемых преобразования: строковое, численное и логическое.
Строковое — Происходит, когда нам нужно что-то вывести. Может быть проведено явно с помощью String(value). Для примитивных значений работает очевидным образом.
Численное — Происходит в математических операциях. Может быть проведено явно с помощью Number(value).
Логическое — Происходит в логических операциях. Может быть проведено явно с помощью Boolean(value).
Строковое преобразование
Строковое преобразование происходит, когда требуется представление чего-либо в виде строки.
Например, alert(value) неявно преобразует значение к строке.
Также мы можем использовать функцию String(value), чтобы явно преобразовать значение к строке:
let value = true;
console.log(`Значение переменной: ${value}, Тип данных: ${typeof value}`); // boolean
value = String(value); // теперь value это строка "true"
console.log(`Значение переменной: ${value}, Тип данных: ${typeof value}`); // string
Преобразование происходит очевидным образом: false становится "false", null становится "null" и т.п.
Численное преобразование
Численное преобразование происходит в математических функциях и выражениях.
Например, когда операция деления / применяется не к числу:
alert( "6" / "2" ); // 3, строки преобразуются в числа
При этом интересно что не каждая математическая операция работает очевидно:
alert( "6" + "2" ); // 62, строки не преобразовались, т.к. такая операция доступна для строк
[!INFO]
Заметим что в примере со сложением, неявного преобразования не произошло потому что для строк операция, обозначаемая знаком+существует, и это операция сложения строк, называемая конкатенацией.
Мы можем использовать функцию Number(value), чтобы явно преобразовать value к числу:
let str = "123";
console.log(`Значение переменной: ${str}, Тип данных: ${typeof str}`); // string
let num = Number(str); // становится числом 123
console.log(`Значение переменной: ${num}, Тип данных: ${typeof num}`); // number
Явное преобразование часто применяется, когда мы ожидаем получить число из строкового контекста, например из текстовых полей форм. Если строка не может быть явно приведена к числу, то результатом преобразования будет NaN.
Например:
let age = Number("А это просто текстовая строка");
console.log(`Значение переменной: ${age}, Тип данных: ${typeof age}`); // NaN, преобразование не удалось
Правила численного преобразования:
| Значение | Преобразуется |
|---|---|
undefined | NaN |
null | 0 |
true | 1 |
false | 0 |
А вот string преобразуется по своей логике: пробельные символы (пробелы, знаки табуляции \t, знаки новой строки \n и т. п.) по краям обрезаются. Далее, если остаётся пустая строка, то получаем 0, иначе из непустой строки «считывается» число. При ошибке результат NaN.
Примеры:
let a = Number(" 123 ");
console.log(`Значение переменной: ${a}, Тип данных: ${typeof a}`); // 123
let b = Number("123z");
console.log(`Значение переменной: ${b}, Тип данных: ${typeof b}`); // NaN (ошибка чтения из-за символа "z")
let c = Number(true);
console.log(`Значение переменной: ${c}, Тип данных: ${typeof c}`); // 1
let d = Number(false);
console.log(`Значение переменной: ${d}, Тип данных: ${typeof d}`); // 0
Учтите, что null и undefined ведут себя по-разному. Так, null становится нулём, тогда как undefined приводится к NaN.
Логическое преобразование
Неявно оно происходит в логических операциях, но также может быть выполнено явно с помощью функции Boolean(value).
Правило преобразования: Значения, которые интуитивно «пустые», вроде 0, пустой строки, null, undefined и NaN, становятся false. Все остальные значения становятся true.
Например:
let a = Boolean(1);
console.log(`Значение переменной: ${a}, Тип данных: ${typeof a}`); // true
let b = Boolean(0);
console.log(`Значение переменной: ${b}, Тип данных: ${typeof b}`); // false
let c = Boolean("Привет!");
console.log(`Значение переменной: ${c}, Тип данных: ${typeof c}`); // true
let d = Boolean("");
console.log(`Значение переменной: ${d}, Тип данных: ${typeof d}`); // false
let e = Boolean("0");
console.log(`Значение переменной: ${e}, Тип данных: ${typeof e}`); // true
let f = Boolean(" ");
console.log(`Значение переменной: ${f}, Тип данных: ${typeof f}`); // пробел это тоже true (любая непустая строка это true)
Заметим, что строчка с нулём "0" — это true!
[!INFO]
Некоторые языки (к примеру, PHP) воспринимают строку"0"какfalse. Но в JavaScript, если строка не пустая, то она всегдаtrue.