В JavaScript примітив (примітивне значення, примітивний тип даних) – це значення, котрі не є об’єктами і не мають методів. JavaScript має 7 примітивних типів даних:

  • string
  • number
  • bigint
  • boolean
  • undefined
  • null
  • symbol

Незмінність (immutable) примітивів

Примітиви в JavaScript – immutable, тобто вони не можуть бути змінені. Важливо не плутати самі примітиви, зі змінними котрі містять значення примітив. Змінній може бути присвоєно нове значення, але поточне значення не може бути зміненим, так само як можуть бути змінені об’єкти, масиви або функції:

let value = 'Тарас';
value.toUpperCase(); // метод рядка не може змінити сам рядок
console.log(value); // OUTPUT: Тарас

value = 'Вадим'; // присвоювання дає змінній примітиву нове (не змінене) значення
console.log(value); // OUTPUT: Вадим

let numbers = [1, 3, 5, 7];
numbers.pop(); // метод масиву змінює масив

console.log(numbers);  // OUTPUT: [ 1, 3, 5 ]

Об’єкти-обгортки для примітивів

В JavaScript усі примітивні значення (крім null та undefined) мають об’єктні еквіваленти, які є обгортками для примітивів (String, Number, BigInt, Boolean і Symbol). Об’єкти-обгортки мають методи, котрі дозволяють маніпулювати примітивами.

Примітиви не мають методів, але поводяться так, ніби вони є. Коли доступ до властивостей здійснюється на примітивах, JavaScript автоматично упаковує значення в об’єкт-обгортку, та натомість отримує доступ до властивості цього об’єкта. Наприклад:

let value = "foo";

console.log(value.toUpperCase()); // OUTPUT: FOO
console.log(value); // OUTPUT: foo

  • змінна value має значення string (примітив). В момент виклику value.toUpperCase(), JavaScript неявно створює об’єкт-обгортку String (котрий знає значення нашого рядка), та викликає String.prototype.toUpperCase() для цього об’єкта.
  • метод toUpperCase() запускається і повертає новий рядок. Спеціальний об’єкт обгортка видаляється, залишаючи тільки примітив, котрий був призначений змінній value.

Тепер перейдемо до поверхневого огляду кожного примітивного типу даних JavaScript. В прикладах для наочності я буду використовувати оператор typeof, котрий допомагає отримати поточний тип значення, що зберігається у змінній.

string

В JavaScript string – це послідовність з нуля або більше символів, що використовується для представлення тексту.

JavaScript має три види лапок для рядкових літералів:

  • подвійні: “some text”
  • одинарні: ‘some text’
  • зворотні: `some text`

Подвійні та одинарні лапки є «простими» лапками. Між ними в JavaScript практично немає різниці.

Зворотні – це лапки «розширеної функціональності». Вони дозволяють вбудовувати змінні та вирази в рядок, загортаючи їх у ${…}. Приклад:

let name = "John";
let text = `Hello ${name}`;

console.log(typeof text); // OUTPUT: string
console.log(text); // OUTPUT: Hello John

number

JavaScript використовує тип number для представлення як цілих чисел, так і чисел з плаваючою комою:

let numberOne = 100;
console.log(typeof numberOne); // OUTPUT: number

let numberTwo = 10.5;
console.log(typeof numberTwo); // OUTPUT: number

Слід звернути увагу, що JavaScript автоматично перетворює число з плаваючою комою на ціле число, якщо воно виглядає як ціле число:

let value = 10.0;
console.log(value); // OUTPUT: 10

Причина полягає в економії використання пам’яті, оскільки значення з плаваючою комою використовує більше пам’яті, ніж ціле значення.

Крім звичайних чисел, існують так звані «спеціальні числові значення», які також належать до цього типу, але не є числами у звичному розумінні цього слова: Infinity, -Infinity та NaN.

Infinity представляє математичну нескінченність ∞. Це особливе значення, котре більше будь-якого числа.

Як приклад, Infinity можна отримати в результаті ділення на нуль:

console.log(5 / 0); // OUTPUT: Infinity

NaN означає обчислювальну помилку. Це результат неправильної або невизначеної математичної операції, наприклад:

console.log('text' / 1); // OUTPUT: NaN

Математичні операції в JavaScript «безпечні». Наприклад можна ділити на нуль, поводитися з не числовими рядками як із числами, тощо. Скрипт не зупиниться з фатальною помилкою (не «помре»). В гіршому випадку буде отримано NaN, як результат виконання.

bigint

Тип bigint представляє цілі числа, більші за (2⁵³ – 1) (тобто 9007199254740991) та менші за -(2⁵³ – 1).

Щоб створити значення типу bigint, необхідно додати n у кінець числового літерала:

let value = 9007199254740991n;
console.log(typeof value); // OUTPUT: bigint

Тип bigInt було додано в JavaScript, щоб дати можливість працювати з цілими числами довільної довжини, без втрати точності. Оскільки технічно, тип number може зберігати великі цілі числа (до 1.7976931348623157 * 10³⁰⁸), але за межами безпечного діапазону цілих чисел ±(2⁵³- 1) буде втрата точності, через те що не всі цифри поміщаються у фіксовану 64-бітну пам’ять. Тому зберігається лише «приблизне» значення.

Наприклад, ці два числа (прямо за межами безпечного діапазону) збігаються:

console.log(9007199254740991 + 1); // OUTPUT: 9007199254740992
console.log(9007199254740991 + 2); // OUTPUT: 9007199254740992

Але якщо використовувати bigInt, точність буде збережено:

console.log(9007199254740991n + 1n); // OUTPUT: 9007199254740992n
console.log(9007199254740991n + 2n); // OUTPUT: 9007199254740993n

boolean

Булевий тип boolean може мати лише два значення: true (істина), або false (брехня).

Цей тип зазвичай використовується для зберігання значень так/ні: true означає «так, правильно», а false означає «ні, не правильно».

Наприклад:

let isActive = false;
console.log(typeof isActive); // OUTPUT: boolean

boolean значення можуть бути результатом порівнянь:

let isGreater = 5 > 0;
console.log(isGreater); // OUTPUT: true

JavaScript також дозволяє перетворювати значення інших типів, у логічні значення true або false, за визначеними правилами.

Для перетворення значень інших типів у логічні значення, використовується функція Boolean(). Наприклад:

let nonEmptyString = 'text';
console.log(Boolean(nonEmptyString)); // OUTPUT: true

let emptyString = '';
console.log(Boolean(emptyString)); // OUTPUT: false

undefined

undefined – це примітивний тип, який має лише одне значення: undefined. За замовчуванням, коли змінну оголошено, але не ініційовано, вона має значення undefined.

Розглянемо наступний приклад:

let value;

console.log(value); // OUTPUT: undefined        
console.log(typeof value); // OUTPUT: undefined

Важливо зазначити, що оператор typeof також повертає undefined значення, якщо викликати його для змінної, котра взагалі не була оголошена:

console.log(typeof undeclaredVar); // OUTPUT: undefined 

null

Тип null – це примітивний тип даних, котрий має лише одне значення: null. Наприклад:

let obj = null;
console.log(typeof obj); // OUTPUT: object

У наведеному вище прикладі визначено, що значення змінної obj невідоме.

Те що операція typeof null повертає object, є відомою помилкою в JavaScript. Пропозиція щодо виправлення була відхилена, бо це може зашкодити збереженню сумісності. Звичайно, що null не є об’єктом. Це спеціальне значення з окремим типом.

В JavaScript null не є «посиланням на неіснуючий об’єкт» або «нульовим покажчиком», як у деяких інших мовах програмування. Це просто спеціальне значення, яке являє собою «нічого», «порожньо» або «значення невідоме».

Також може бути корисним ознайомитись: JavaScript – різниця між undefined та null

symbol

JavaScript представив новий примітивний тип symbol у ES6. На відміну від інших примітивних типів, тип symbol не має літеральної форми.

Щоб створити значення типу symbol, потрібно викликати функцію Symbol() наступним чином:

let symbolValue = Symbol();
console.log(typeof symbolValue); // OUTPUT: symbol

Також функції Symbol() можна передати опціональний рядок description, в якості аргументу:

let symbolValue = Symbol('ok');

console.log(symbolValue); // OUTPUT: Symbol(ok)
console.log(symbolValue.description); // OUTPUT: ok

description може бути корисним для налагодження програми.

Значення symbol є унікальними:

let value1 = Symbol('ok');
let value2 = Symbol('ok');

console.log(value1 === value2); // OUTPUT: false

Хоча value1 і value2 містять однаковий description, це різні значення.

Основне призначення symbol – отримувати унікальне значення кожного разу, коли вони створюються. Можна думати про symbol, як про спеціальні токени, котрі гарантують унікальність (як наприклад UUID).

symbol часто використовуються для ідентифікації властивостей об’єктів, щоб уникнути конфліктів імен, оскільки жоден symbol не дорівнює іншому:

let name = Symbol();
let person = {
  [name]: 'Jhon'
};

console.log(person[name]); // OUTPUT: Jhon

Це був загальний огляд примітивних типів даних в JavaScript. Огляд кожного типу, з більш детальним розбором особливостей використання, потребує окремого запису.


Мітки: