Короткий огляд символів JavaScript

Символи

Символи - нові примітивнітип, введений в ES6. Символи - це абсолютно унікальні ідентифікатори. Як і їх примітивні аналоги ( Number , String , Boolean ), їх можна створити за допомогою заводської функції, Symbol()яка повертає символ.

const symbol = Symbol('description')

Щоразу, коли ви викликаєте заводську функцію, створюється новий унікальний символ. Необов’язковий параметр із рядковим значенням - це описовий рядок, який відображається під час друку символу.

> symbol Symbol(description)

Кожен символ, який повертається, Symbol()є унікальним, тому кожен символ має свою власну ідентичність:

> Symbol() === Symbol() false

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

> typeof symbol 'symbol'

Приклад використання: Символи як ключі непублічних властивостей

Щоразу, коли в JavaScript є ієрархії успадкування, у вас є два типи властивостей (наприклад, створені за допомогою класів, чисто прототипний підхід):

  • Відкриті властивості бачать клієнти коду
  • Приватні властивості використовуються всередині частин, що складають ієрархію успадкування (наприклад, класи, об'єкти).

Для зручності загальнодоступні властивості зазвичай мають рядкові ключі. Але для приватних властивостей із рядковими ключами випадкові зіткнення імен можуть стати проблемою. Тому символи - хороший вибір.

Наприклад, в наступному коді, символи використовуються для приватних властивостей _counterі _action:

const _counter = Symbol('counter'); const _action = Symbol('action'); class Countdown { constructor(counter, action) { this[_counter] = counter; this[_action] = action; } dec() { let counter = this[_counter]; if (counter < 1) return; counter--; this[_counter] = counter; if (counter === 0) { this[_action](); } } }

Зауважте, що символи захищають вас лише від зіткнень імен, а не від несанкціонованого доступу. Ви можете дізнатись усі ключі властивостей об’єкта, включаючи символи, за допомогою:

const obj = { [Symbol('my_key')] : 1, enum : 2, nonEnum : 3 }; Object.defineProperty(obj, 'nonEnum', { enumerable: false }); // Making 'nonEnum' as not enumerable. // Ignores symbol-valued property keys: > Object.getOwnPropertyNames(obj) ['enum', 'nonEnum'] // Ignores string-valued property keys: > Object.getOwnPropertySymbols(obj) [Symbol(my_key)] // Considers all kinds of keys: > Reflect.ownKeys(obj) [Symbol(my_key),'enum', 'nonEnum'] // Only considers enumerable property keys that are strings: > Object.keys(obj) ['enum']

Чи справді нам потрібні символи?

Використовуйте символи, коли ваша потреба є однією з таких:

  • Enum: дозволяє вам визначати константи із семантичними іменами та унікальними значеннями.
const directions = { UP : Symbol( ‘UP’ ), DOWN : Symbol( ‘DOWN’ ), LEFT : Symbol( ‘LEFT’ ), RIGHT: Symbol( ‘RIGHT’ ) };
  • Зіткнення імен: коли ви хочете запобігти зіткненню з ключами в об'єктах
  • Конфіденційність: коли ви не хочете, щоб властивості об’єкта були незліченними
  • Протоколи: Визначити спосіб ітерації об’єкта.

    Уявіть, наприклад, бібліотеку, як dragulaвизначення протоколу через Symbol.for(dragula.moves). Ви можете додати метод до цього Symbolдо будь-якого елемента DOM. Якщо елемент DOM слідує протоколу, тоді dragulaможе викликати визначений el[Symbol.for('dragula.moves')]()користувачем метод, щоб підтвердити, чи можна переміщувати елемент.

  • Загальновідомі символи: Окрім визначених користувачем символів, JavaScript має деякі вбудовані символи. Вони представляють поведінку внутрішньої мови, яка не зазнавала розробників у <ES5. Більше інформації тут .

Висновок

Symbolsв JavaScript може забезпечити унікальність рівня доступу до об'єктів. Варто всім розробникам добре знати їх та різні варіанти їх використання.

code = coffee + developer