Объекты и примитивы в JavaScript
Объекты (в том числе и массивы, как вы уже знаете) считаются сложными типами данных. Строки, числа, логические значения считаются простыми, или типами данных. Их часто так и называют — , подразумевая все то, что не является объектом.
В JavaScript семь примитивных типов данных: string , number , boolean , null , undefined , symbol , bigint . Запомните их количество и названия — это часто спрашивают на собеседованиях.
Дан следующий код:
let test =
Какой тип данных выведется в консоль? Это примитив или объект?
Дан следующий код:
let test =
Какой тип данных выведется в консоль? Это примитив или объект?
Дан следующий код:
let test = [1, 2, 3]; console.log(test);
Какой тип данных выведется в консоль? Это примитив или объект?
Дан следующий код:
let test = [1, 2, 3]; console.log(test[1]);
Какой тип данных выведется в консоль? Это примитив или объект?
Дан следующий код:
let test1 = [1, 2, 3]; let test2 = 1; console.log(test1);
Какой тип данных выведется в консоль? Это примитив или объект?
Дан следующий код:
let test1 = [1, 2, 3]; let test2 = 1; console.log(test1[test2]);
Какой тип данных выведется в консоль? Это примитив или объект?
Не подсматривая в учебник перечислите все примитивные типы данных в JavaScript.
Типы данных
Значение в JavaScript всегда относится к данным определённого типа. Например, это может быть строка или число.
Есть восемь основных типов данных в JavaScript. В этой главе мы рассмотрим их в общем, а в следующих главах поговорим подробнее о каждом.
Переменная в JavaScript может содержать любые данные. В один момент там может быть строка, а в другой – число:
// Не будет ошибкой let message = "hello"; message = 123456;
Языки программирования, в которых такое возможно, называются «динамически типизированными». Это значит, что типы данных есть, но переменные не привязаны ни к одному из них.
Число
let n = 123; n = 12.345;
Числовой тип данных ( number ) представляет как целочисленные значения, так и числа с плавающей точкой.
Существует множество операций для чисел, например, умножение * , деление / , сложение + , вычитание — и так далее.
Кроме обычных чисел, существуют так называемые «специальные числовые значения», которые относятся к этому типу данных: Infinity , -Infinity и NaN .
-
Infinity представляет собой математическую бесконечность ∞. Это особое значение, которое больше любого числа. Мы можем получить его в результате деления на ноль:
alert( 1 / 0 ); // Infinity
Или задать его явно:
alert( Infinity ); // Infinity
alert( "не число" / 2 ); // NaN, такое деление является ошибкой
Значение NaN «прилипчиво». Любая математическая операция с NaN возвращает NaN :
alert( NaN + 1 ); // NaN alert( 3 * NaN ); // NaN alert( "не число" / 2 - 1 ); // NaN
Математические операции – безопасны
Математические операции в JavaScript «безопасны». Мы можем делать что угодно: делить на ноль, обращаться с нечисловыми строками как с числами и т.д.
Скрипт никогда не остановится с фатальной ошибкой (не «умрёт»). В худшем случае мы получим NaN как результат выполнения.
Специальные числовые значения относятся к типу «число». Конечно, это не числа в привычном значении этого слова.
Подробнее о работе с числами мы поговорим в главе Числа.
BigInt
В JavaScript тип number не может безопасно работать с числами, большими, чем (2 53 -1) (т. е. 9007199254740991 ) или меньшими, чем -(2 53 -1) для отрицательных чисел.
Если говорить совсем точно, то, технически, тип number может хранить большие целые числа (до 1.7976931348623157 * 10 308 ), но за пределами безопасного диапазона целых чисел ±(2 53 -1) будет ошибка точности, так как не все цифры помещаются в фиксированную 64-битную память. Поэтому можно хранить «приблизительное» значение.
Например, эти два числа (прямо за пределами безопасного диапазона) совпадают:
console.log(9007199254740991 + 1); // 9007199254740992 console.log(9007199254740991 + 2); // 9007199254740992
То есть все нечетные целые числа, большие чем (2 53 -1) , вообще не могут храниться в типе number .
В большинстве случаев безопасного диапазона чисел от -(2 53 -1) до (2 53 -1) вполне достаточно, но иногда нам требуется весь диапазон действительно гигантских целых чисел без каких-либо ограничений или пропущенных значений внутри него. Например, в криптографии или при использовании метки времени («timestamp») с микросекундами.
Тип BigInt был добавлен в JavaScript, чтобы дать возможность работать с целыми числами произвольной длины.
Чтобы создать значение типа BigInt , необходимо добавить n в конец числового литерала:
// символ "n" в конце означает, что это BigInt const bigInt = 1234567890123456789012345678901234567890n;
Так как необходимость в использовании BigInt –чисел появляется достаточно редко, мы рассмотрим их в отдельной главе BigInt. Ознакомьтесь с ней, когда вам понадобятся настолько большие числа.
В данный момент BigInt поддерживается только в браузерах Firefox, Chrome, Edge и Safari, но не поддерживается в IE.
Строка
Строка ( string ) в JavaScript должна быть заключена в кавычки.
let str = "Привет"; let str2 = 'Одинарные кавычки тоже подойдут'; let phrase = `Обратные кавычки позволяют встраивать переменные $`;
В JavaScript существует три типа кавычек.
- Двойные кавычки: «Привет» .
- Одинарные кавычки: ‘Привет’ .
- Обратные кавычки: `Привет` .
Двойные или одинарные кавычки являются «простыми», между ними нет разницы в JavaScript.
Обратные же кавычки имеют расширенную функциональность. Они позволяют нам встраивать выражения в строку, заключая их в $ . Например:
let name = "Иван"; // Вставим переменную alert( `Привет, $!` ); // Привет, Иван! // Вставим выражение alert( `результат: $` ); // результат: 3
Выражение внутри $ вычисляется, и его результат становится частью строки. Мы можем положить туда всё, что угодно: переменную name , или выражение 1 + 2 , или что-то более сложное.
Обратите внимание, что это можно делать только в обратных кавычках. Другие кавычки не имеют такой функциональности встраивания!
alert( "результат: $" ); // результат: $ (двойные кавычки ничего не делают)
Мы рассмотрим строки более подробно в главе Строки.
Нет отдельного типа данных для одного символа.
В некоторых языках, например C и Java, для хранения одного символа, например «a» или «%» , существует отдельный тип. В языках C и Java это char .
В JavaScript подобного типа нет, есть только тип string . Строка может содержать ноль символов (быть пустой), один символ или множество.
Булевый (логический) тип
Булевый тип ( boolean ) может принимать только два значения: true (истина) и false (ложь).
Такой тип, как правило, используется для хранения значений да/нет: true значит «да, правильно», а false значит «нет, не правильно».
let nameFieldChecked = true; // да, поле отмечено let ageFieldChecked = false; // нет, поле не отмечено
Булевые значения также могут быть результатом сравнений:
let isGreater = 4 > 1; alert( isGreater ); // true (результатом сравнения будет "да")
Мы рассмотрим булевые значения более подробно в главе Логические операторы.
Значение «null»
Специальное значение null не относится ни к одному из типов, описанных выше.
Оно формирует отдельный тип, который содержит только значение null :
let age = null;
В JavaScript null не является «ссылкой на несуществующий объект» или «нулевым указателем», как в некоторых других языках.
Это просто специальное значение, которое представляет собой «ничего», «пусто» или «значение неизвестно».
В приведённом выше коде указано, что значение переменной age неизвестно.
Значение «undefined»
Специальное значение undefined также стоит особняком. Оно формирует тип из самого себя так же, как и null .
Оно означает, что «значение не было присвоено».
Если переменная объявлена, но ей не присвоено никакого значения, то её значением будет undefined :
let age; alert(age); // выведет "undefined"
Технически мы можем присвоить значение undefined любой переменной:
let age = 123; // изменяем значение на undefined age = undefined; alert(age); // "undefined"
…Но так делать не рекомендуется. Обычно null используется для присвоения переменной «пустого» или «неизвестного» значения, а undefined – для проверок, была ли переменная назначена.
Объекты и символы
Тип object (объект) – особенный.
Все остальные типы называются «примитивными», потому что их значениями могут быть только простые значения (будь то строка, или число, или что-то ещё). В объектах же хранят коллекции данных или более сложные структуры.
Объекты занимают важное место в языке и требуют особого внимания. Мы разберёмся с ними в главе Объекты после того, как узнаем больше о примитивах.
Тип symbol (символ) используется для создания уникальных идентификаторов в объектах. Мы упоминаем здесь о нём для полноты картины, изучим этот тип после объектов.
Оператор typeof
Оператор typeof возвращает тип аргумента. Это полезно, когда мы хотим обрабатывать значения различных типов по-разному или просто хотим сделать проверку.
У него есть две синтаксические формы:
// Обычный синтаксис typeof 5 // Выведет "number" // Синтаксис, напоминающий вызов функции (встречается реже) typeof(5) // Также выведет "number"
Если передается выражение, то нужно заключать его в скобки, т.к. typeof имеет более высокий приоритет, чем бинарные операторы:
typeof 50 + " Квартир"; // Выведет "number Квартир" typeof (50 + " Квартир"); // Выведет "string"
Другими словами, скобки необходимы для определения типа значения, которое получилось в результате выполнения выражения в них.
Вызов typeof x возвращает строку с именем типа:
typeof undefined // "undefined" typeof 0 // "number" typeof 10n // "bigint" typeof true // "boolean" typeof "foo" // "string" typeof Symbol("id") // "symbol" typeof Math // "object" (1) typeof null // "object" (2) typeof alert // "function" (3)
Последние три строки нуждаются в пояснении:
- Math — это встроенный объект, который предоставляет математические операции и константы. Мы рассмотрим его подробнее в главе Числа. Здесь он служит лишь примером объекта.
- Результатом вызова typeof null является «object» . Это официально признанная ошибка в typeof , ведущая начало с времён создания JavaScript и сохранённая для совместимости. Конечно, null не является объектом. Это специальное значение с отдельным типом.
- Вызов typeof alert возвращает «function» , потому что alert является функцией. Мы изучим функции в следующих главах, где заодно увидим, что в JavaScript нет специального типа «функция». Функции относятся к объектному типу. Но typeof обрабатывает их особым образом, возвращая «function» . Так тоже повелось от создания JavaScript. Формально это неверно, но может быть удобным на практике.
Итого
В JavaScript есть 8 основных типов данных.
- Семь из них называют «примитивными» типами данных:
- number для любых чисел: целочисленных или чисел с плавающей точкой; целочисленные значения ограничены диапазоном ±(2 53 -1) .
- bigint для целых чисел произвольной длины.
- string для строк. Строка может содержать ноль или больше символов, нет отдельного символьного типа.
- boolean для true / false .
- null для неизвестных значений – отдельный тип, имеющий одно значение null .
- undefined для неприсвоенных значений – отдельный тип, имеющий одно значение undefined .
- symbol для уникальных идентификаторов.
- object для более сложных структур данных.
Оператор typeof позволяет нам увидеть, какой тип данных сохранён в переменной.
- Имеет две формы: typeof x или typeof(x) .
- Возвращает строку с именем типа. Например, «string» .
- Для null возвращается «object» – это ошибка в языке, на самом деле это не объект.
В следующих главах мы сконцентрируемся на примитивных значениях, а когда познакомимся с ними, перейдём к объектам.
Типы данных в JavaScript
В JavaScript определены семь встроенных типов данных. Шесть примитивных типов и один тип, который представляет из себя структуру данных:
-
boolean — логический тип данных, который принимает значения true иди false
let val = false; val = true;
let val = 50; val = 3.14159; val = -200;
Этот тип представляет из себя число двойной точности, подробнее о нём можно прочитать здесь. Ноль в JavaScript имеет два представления: -0 и +0 . («0» это синоним +0). На практике это имеет малозаметный эффект. Например, выражение +0 === -0 является истинным. А также есть специальные значения, которые по сути не являются числами, но принадлежат к числовому типу данных: Infinity (бесконечность) и NaN (Not a Number — “Не Число”)
let inf = Infinity; // прямое присвоение бесконечности inf = 57 / 0; // Infinity получится при делении на ноль inf = -Infinity; // есть отрицательная бесконечность inf = 57 / -0; // -Infinity let notNumber = NaN; notNumber = "строка" * 5; // При ошибке вычисления вернёт NaN
Для получения самого большого или самого меньшего доступного значения в пределах +/-Infinity , можно использовать константы Number.MAX_VALUE или Number.MIN_VALUE . А начиная с ECMAScript 2015, вы также можете проверить, находится ли число в безопасном для целых чисел диапазоне, используя метод Number.isSafeInteger() , либо константы Number.MAX_SAFE_INTEGER и Number.MIN_SAFE_INTEGER . За пределами этого диапазона операции с целыми числами будут небезопасными, и возвращать приближённые значения. Например, подумайте над следующей задачей. Какое значение должно быть у переменной value , чтобы после выполнению кода ниже, в консоли отобразились значения, указанные в комментариях?
let value = ? console.log(i * i) // 0 console.log(i + 1) // 1 console.log(i - 1) // -1 console.log(i / i) // 1
let str = "Это строка"; console.log(str[0]); // Э - первый символ строки console.log(str.length); // 10 console.log(str[str.length - 1]); // а - последний символ строки str = 'А это "строка в двойных кавычках" внутри строки';
Также соединения строк (конкатенации) можно использовать оператор + или метод String.concat() . Также для составления строк с использованием значений переменных удобно применять шаблонизацию через обратные кавычки — `строка с переменной $
` let name = "Василий"; let helloMsg = "Привет, " + name + "!"; // Привет, Василий! let newHelloMsg = name.concat(", здравствуйте. ", "Удачного дня!"); // Василий, здравствуйте. Удачного дня! //Для помещения значений переменных в шаблон используется конструкция $ helloMsg = `Привет, $name>`; // Привет, Василий!
let sym1 = Symbol(); let sym2 = Symbol("foo");
let data = null;
let data; console.log(data); // undefined
Определение типов оператором typeof
Оператор typeof возвращает строку, указывающую тип операнда. Синтаксис вызова этого оператора: typeof operand . Например:
// Числа console.log(typeof 42); // "number" console.log(typeof Infinity); // "number" console.log(typeof NaN); // "number", несмотря на то, что смысл этого значения "Not-A-Number" (не число) // Строки console.log(typeof "строка"); // "string" let name = "Василий"; console.log(typeof `Привет, $name>`); // "string" // Булевы значения console.log(typeof true); // "boolean" console.log(typeof false); // "boolean" // Символы console.log(typeof Symbol()); // "symbol" // undefined let declaredButUndefinedVariable; console.log(typeof declaredButUndefinedVariable); // "undefined"; // Объекты console.log(typeof a: 1 >); // "object" console.log(typeof [1, 2, 3]); // такая структура данных, как массив, тоже "object"
Но есть два значения, для которых оператор typeof не совсем корректно отражает их тип:
-
Значение null , для него typeof возвращает тип “object”, что является официально признанной ошибкой в языке, которая сохраняется для совместимости. На самом деле это не объект, а отдельный тип данных null .
// null console.log(typeof null); // "object"
// function console.log(typeof function() <>); // "function"
Примитивные и ссылочные типы данных
Особенность примитивных типов данных заключается в том, что они неизменяемы (иммутабельны) и передаются по значению. В отличие от объектов, которые передаются по ссылке. При этом важно понимать, что объект или примитив, это не сама переменная, а соответствующий указатель на объект или само значение примитивного типа, которое этой переменной присвоено.
Например рассмотрим следующий код:
// Примитивный тип number let num = 5; // Функция для прибавления двойки к примитиву function addTwo(num) num = num + 2; > // Вызов функции addTwo(num); console.log(num); // 5
Что происходит после вызова этой функций?
В первую функцию addTwo в качестве параметра передаётся значение переменной num из глобальной области видимости, то есть 5 . Таким образом Запись Окружения этой функции после вызова будет выглядеть так:
let num = 5; function addTwo(num) // на этапе создания контекста - , где num, это локальная переменная функции addTwo num = num + 2; // на этапе выполнения контекста, эта строка изменит запись на > addTwo(num); console.log(num); // 5
Но что же и этом произойдет со значением переменной num из глобальной области видимости? В действительности её значение останется таким же, как и было до вызова функции addTwo , так как в неё просто было скопировано значение этой переменной. И все манипуляции уже производились над другой переменной из области видимости функции addTwo . В текущей ей реализации она просто производит операцию над локальной переменной и не возвращает никакого определенного значения (а точнее она вернёт undefined ).
Если переписать эту функцию, чтобы она возвращала новое значение локальной переменной num и потом присвоить это значение обратно уже в глобальную переменную num , то только в таком случае её значение поменяется:
let num = 5; function addTwo(num) // на этапе создания контекста - num = num + 2; // на этапе выполнения контекста, эта строка изменит запись на return num; // вернуть результатом функции новое значение > num = addTwo(num); // присвоить результат функции как новое значение переменной console.log(num); // 7
Этот пример отражает то, что примитивы передаются по значению и какие-либо действия производятся над копиями этих значений. Поэтому если явно не возвращать или не присваивать новый результат в соответствующие переменные, то никаких изменений переменных не произойдет.
Теперь рассмотрим как передаются значения объектов:
// Ссылочный тип object let obj = key: 5 >; // Функция для прибавления двойки к свойству объекта function addTwoObj(obj) obj.key = obj.key + 2; > // Вызов функции addTwoObj(obj); console.log(obj.key); // 7
Почему в данном случае свойство объекта изменилось, хотя никаких дополнительных действий по возврату нового значения и его присваивания не происходило?
В этом случае важно понимать, что переменная содержит не сам объект, а грубо говоря указатель (ссылку) на то место в памяти, где этот объект хранится. Поэтому параметром в функцию будет передаваться именно это ссылка объект и Запись Окружения этой функции после вызова будет выглядеть так:
let obj = key: 5 >; function addTwoObj(obj) // на этапе создания контекста - >, здесь переменная obj опять же является уже локальной переменной функции addTwoObj obj.key = obj.key + 2; // на этапе выполнения контекста, эта строка сначала по переданной ссылке в obj найдет сам объект < key: 5 >изменит свойство key самого объекта, а не его копии. Запись Окружения станет > > addTwoObj(obj); // переменная obj хранит в себе ссылку а объект < key: 5 >, поэтому параметром передаётся именно эта ссылка console.log(obj.key); // Был изменен сам объект, который был передан по ссылке, поэтому значение его свойства будет 7
А что выведется в консоль, если изменить локальную переменную obj ?
let obj = key: 5 >; function addTwoObj(obj) obj.key = obj.key + 2; obj = num: 6 >; // присвоить другой объект obj = null; // или же вообще присвоить нулевое значение > addTwoObj(obj); console.log(obj.key);
Здесь в консоли снова выведется 7 . Так как в функции addTwoObj переменная obj является локальной и затеняет одноименную глобальную переменную, то присваивания ей в функции новых значений никак не отразится на глобальной переменной obj . Это лишь приведет к перезаписи переданной ссылки на объект < key: 5 >новыми значениями.
let obj = key: 5 >; function addTwoObj(obj) // на этапе создания контекста - >, здесь переменная obj опять же является уже локальной переменной функции addTwoObj obj.key = obj.key + 2; // на этапе выполнения контекста, эта строка сначала по переданной ссылке в obj найдет сам объект < key: 5 >изменит свойство key самого объекта, а не его копии. Запись Окружения станет > obj = num: 6 >; // после выполнения этой строки измениться лишь значение локальной переменной в Записи Окружения: > obj = null; // а здесь вообще в локальную переменную запишется значение null примитивного типа > addTwoObj(obj); // переменная obj хранит в себе ссылку а объект < key: 5 >, поэтому параметром передаётся именно эта ссылка console.log(obj.key); // Был изменен сам объект, который был передан по ссылке, поэтому значение его свойства будет 7
Обертки примитивных типов в JavaScript
В отличие от объектов, у примитивов нет своих методов, но у всех них, за исключением null и undefined , есть объектные аналоги, который оборачивает значение примитивного типа и позволяют производить над ними различные преобразования:
- String для string примитива.
- Number для number примитива.
- Boolean для boolean примитива.
- Symbol для symbol примитива.
Что происходит когда вызывается какой-либо метод у примитивного типа данных, например:
let char = "текст".charAt(1); // е
Так как у примитивного типа строки нет своих методов, то сначала создаётся его копия и неявно оборачивается в его объектный аналог с помощью конструктора new String(something) . И уже в рамках этого объекта существует набор различных встроенных методов, дин из них — charAt() , который возвращает символ строки по указанной позиции. После вызова метода возвращается его результат и эта объектная обёртка уничтожается. Поэтому сам вызов метода никак не влияет на изначальное значение примитива, а только возвращает вычисленное значение.
Явно этот код можно записать так:
let char = new String("текст").charAt(1); // "е"
И именно поэтому вызов следующих методов будет лишь возвращать новые значения и никак не повлияет на исходную переменную str :
let str = "текст"; let upper = str.toUpperCase(); let substr = str.substring(0, 3); console.log(upper); // "ТЕКСТ" console.log(substr); // "тек" console.log(str); // "текст"
У каждой такой объектной обертки есть метод valueOf() , который возвращает соответствующее значение примитивного типа. Например:
var numObj = new Number(10); console.log(typeof numObj); // object var num = numObj.valueOf(); console.log(num); // 10 console.log(typeof num); // number
Обычно не принято явно вызывать конструкторы для примитивных типов, так как они предназначены только для внутреннего использования и явное их использование без четкого понимания их поведения может приводить к различным ошибкам.
Дата изменения: February 26, 2023
Поделиться
Обнаружили ошибку или хотите добавить что-то своё в документацию? Отредактируйте эту страницу на GitHub!
Что является примитивными типами данных в javascript
Все используемые данные в javascript имеют определенный тип. В JavaScript имеется восемь типов данных:
- String : представляет строку
- Number : представляет числовое значение
- BigInt : предназначен для представления очень больших целых чисел
- Boolean : представляет логическое значение true или false
- Undefined : представляет одно специальное значение — undefined и указывает, что значение не установлено
- Null : представляет одно специальное значение — null и указывает на отсутствие значения
- Symbol : представляет уникальное значение, которое часто применяется для обращения к свойствам сложных объектов
- Object : представляет комплексный объект
Первые семь типов представляют примитивные типы данных. Последний тип — Object представляет сложный, комплексный тип данных, который состоит из значений примитивных типов или других объектов. Рассмотрим основные примитивные типы данных.
Числовые данные
Number
Тип Number представляет числа в JavaScript, которые могут быть целыми или дробными:
- Целые числа, например, 35. Мы можем использовать как положительные, так и отрицательные числа. Диапазон используемых чисел: от -2 53 до 2 53
- Дробные числа (числа с плавающей точкой). В качестве разделителя дробной и целой части применяется точка, например, 3.5575 . Опять же можно использовать как положительные, так и отрицательные числа. Для чисел с плавающей точкой используется тот же диапазон: от -2 53 до 2 53
const x = 45; const y = 123.897; const z = -0.123;
JavaScript поддерживает возможность определять числа в двоичной, восьмеричной и шестнадцатеричной системах, что очень удобно, если нам предстоить проводить поразрядные операции с отдельными битами числа. Для определения числа в двоичной системе, перед числом указывается префикс 0b :
const num1 = 0b1011; // число 11 в десятичной системе console.log(num1); // 11
В данном случае константа num1 равна 0b1011 , что в десятичной системе эквивалентно 11.
Для определения числа в восьмеричной системе, перед числом указывается префикс 0o :
const num1 = 0o11; // число 9 в десятичной системе console.log(num1); // 9
Для определения числа в шестнадцатеричной системе, перед числом указывается префикс 0x :
const num1 = 0xff; // число 255 в десятичной системе console.log(num1); // 255 const num2 = 0x1A; // число 26 в десятичной системе console.log(num2); // 26
Начиная со стандарта ECMA2021 в JavaScript для увеличения читабельности в качестве разделителя между разрядами можно использовать символ подчеркивания _:
const num1 = 1234567; const num2 = 123_4567; // число равное num1 const num3 = 1234567890; const num4 = 12_3456_7890; // число равное num3
Тип BigInt
Тип BigInt добавлен в последних стандартах JavaScript для представления очень больших целых чисел, которые выходят за пределы диапазона типа number. Это не значит, что мы не можем совсем работать с большими числами с помощью типа number, но работа с ними в случае с типом number будет сопряжена с проблемами. Рассмотрим небольшой пример:
let num = 9007199254740991 console.log(num); // 9007199254740991 console.log(num + 1); // 9007199254740992 console.log(num + 2); // 9007199254740992
Здесь переменной num присваивается максимальное значение. И далее прибавляем к ней некоторые значения и выводим на консоль результат. И результаты могут нас смутить, особенно в случае прибавления числа 2.
Стоит отметить, что тип Number ограничен, хотя и позволяет оперировать довольно большим диапазоном чисел. В частности, мы можем использовать специальные константы Number.MIN_VALUE и Number.MAX_VALUE для проверки минимального и максимального возможных значений для типа Number:
console.log(Number.MIN_VALUE); // 5e-324 console.log(Number.MAX_VALUE); // 1.7976931348623157e+308
Например, рассмотрим следующий пример:
const num = 9223372036854775801; console.log(num); // 9223372036854776000
В силу ограничений типа Number на консоли мы увидим несколько другое число, нежели мы присвоили константе num. Это может негативно влиять на точность в вычислениях. И для подобных подобных чисел как раз предназначен тип BigInt . Для определения числа как значения типа BigInt в конце числа добавляется суффикс n :
let dimension = 19007n; const value = 2545n;
Например, изменим из предыдущего примера тип number на bigint:
const num = 9223372036854775801n; console.log(num); // 9223372036854775801n
Теперь консоль выводит корректный результат.
Тип Boolean
Тип Boolean представляет булевые или логические значения true (верно) и false (ложно):
const isAlive = true; const isDead = false;
Строки String
Тип String представляет строки. Для определения строк применяются кавычки, причем, можно использовать как двойные, так одинарные, так и косые кавычки. Единственно ограничение: тип закрывающей кавычки должен быть тот же, что и тип открывающей, то есть либо обе двойные, либо обе одинарные.
const user = "Tom"; const company = 'Microsoft'; const language = `JavaScript`; console.log(user); console.log(company); console.log(language);
Если внутри строки встречаются кавычки, то мы их должны экранировать слешем. Например, пусть у нас есть текст «Бюро «Рога и копыта»» . Теперь экранируем кавычки:
const company = "Бюро \"Рога и копыта\"";
Также мы можем внутри стоки использовать другой тип кавычек:
constcompany1 = "Бюро 'Рога и копыта'"; const company2 = 'Бюро "Рога и копыта"';
Также строка может содержать специальные символы — управляющие последовательности, которые интерпретируются определенным образом. Самые распространенные последовательности — это «\n» (перевод на другую строку) и «\t» (табуляция). Например:
const text = "Hello METANIT.COM\nHello\tWorld"; console.log(text);
При выводе на консоль текст из константы text будет интерпретироваться следующим образом:
Hello METANIT.COM Hello World
Интерполяция
Использование косых кавычек позволяет нам применять такой прием как интерполяция — встраивать данные в строку. Например:
const user = "Tom"; const text = `Name: $`; console.log(text); // Name: Tom
Для встраивания значений выражений (например, значений других переменных и констант) в строку перед выражением ставится знак доллара $ , после которого в фигурных скобках указывается выражение. Так, в примере выше $ означает, что в этом месте строки надо встроить значение переменной user .
Подобным образом можно встраивать и больше количество данных:
const user = "Tom"; const age = 37; const isMarried = false; const text = `Name: $ Age: $ IsMarried: $`; console.log(text); // Name: Tom Age: 37 IsMarried: false
Кроме интерполяции косые кавычки позволяют определять многострочный текст:
const text = `Мы все учились понемногу Чему-нибудь и как-нибудь, Так воспитаньем, слава богу, У нас немудрено блеснуть.`; console.log(text);
Консольный вывод браузера:
Мы все учились понемногу Чему-нибудь и как-нибудь, Так воспитаньем, слава богу, У нас немудрено блеснуть.
null и undefined
undefined указывает, что значение не определено или не установлено. Например, когда мы только определяем переменную без присвоения ей начального значения, она представляет тип undefined:
let email; console.log(email); // выведет undefined
Присвоение значение null означает, что у переменной отсутствует значение:
let email; console.log(email); // undefined email = null; console.log(email); // null
Стоит отметить, что хотя в принципе можно переменной присвоить значение undefined , как в следующем случае:
let email = "tome@mimimail.com"; email = undefined; // установим тип undefined console.log(email); // undefined
Но основной смысл undefined состоит в том, что переменная неинициализирована, что обычно происходит до первого присвоения ей какого-либо значения. Поэтому обычно не предполагается, что переменной явным образом будет присваиваться значение undefined . В тоже время этот тип может быть полезен — мы можем использовать его на проверку инициализации переменной. Но если же нам надо указать, что у переменной нет никакого значения, то ей присваивается null , а не undefine .
object
Тип object представляет сложный объект. Простейшее определение объекта представляют фигурные скобки:
const user = <>;
Объект может иметь различные свойства и методы:
const user = ; console.log(user.name);
В данном случае объект называется user, и он имеет два свойства: name и age, которые в качестве значения принимают данные других типов. Это краткое описание объектов, более подробно объекты мы рассморим в последующих статьях.
Слабая/динамическая типизация
JavaScript является языком со слабой и динамической типизацией. Это значит, что переменные могут динамически менять тип. Например:
let id; // тип undefined console.log(id); id = 45; // тип number console.log(id); id = "45"; // тип string console.log(id);
Несмотря на то, что во втором и третьем случае консоль выведет нам число 45, но во втором случае переменная id будет представлять число, а в третьем случае — строку.
Оператор typeof
С помощью оператора typeof можно получить тип переменной, что может быть полезно, когда в зависимости от типа переменной необходимо выполнить те или иные действия:
let id; console.log(typeof id); // undefined id = 45; console.log(typeof id); // number id = 45n; console.log(typeof id); // bigint id = "45"; console.log(typeof id); // string
Стоит отметить, что для значения null оператор typeof возвращает значение «object», несмотря на то, что согласно спецификации JavaScript значение null представляет отдельный тип.