Бърз преглед на 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