Практическое руководство по символам в JavaScript

Практическое руководство по символам в JavaScript

От автора: в ES6 появились символы Javasript, как способ предотвращения конфликтов имен свойств. В качестве дополнительного бонуса символы также позволяют моделировать закрытые свойства в JavaScript 2015-2019.

Вступление

Самый простой способ создать символ в JavaScript — это вызвать функцию Symbol(). 2 ключевых вещи, которые делают символы такими особенными:

Символы могут использоваться как ключи объекта. В качестве ключей объекта могут использоваться только строки и символы.

Не существует двух одинаковых символов.

Хотя при вызове Symbol() создается впечатление, что символы являются объектами, символы на самом деле являются примитивным типом JavaScript. Использование Symbol в качестве конструктора с new выдает ошибку.

Descriptions

Функция Symbol() принимает один параметр, строка description. description предназначен только для целей отладки — description отображается в символе toString(). Однако два символа с одинаковым description не равны.

Существует также глобальный реестр символов. Создание символа с использованием Symbol.for() добавляет символ в глобальный реестр, ключ которого обозначен символом description. Другими словами, если вы создадите два символа с одинаковым описанием, используя Symbol.for() для этих двух символов, они будут равны.

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

Конфликты имен

Первым встроенным символом в JavaScript был символ Symbol.iterator ES6. Объект с функцией Symbol.iterator считается итеративным. Это означает, что вы можете использовать этот объект как правую часть for/of цикла.

Почему Symbol.iterator символ, а не строка? Предположим, вместо использования итеративной спецификации Symbol.iterator проверяется наличие строкового свойства ‘iterator’. Кроме того, предположим, что у вас был следующий класс, который должен был быть повторяемым.

Экземпляры MyClass будут повторяемыми, что позволит вам перебирать ключи объекта. Но у вышеупомянутого класса также есть потенциальный недостаток. Предположим, что злоумышленник передал объект со свойством iterator в MyClass.

Если бы вы использовали for/of с obj, JavaScript выдал бы TypeError: obj is not iterable. Потому что пользовательская функция iterator перезаписывает свойство итератора класса. Это похоже на проблему безопасности с загрязнением прототипа, когда простое копирование пользовательских данных может вызвать проблемы со специальными свойствами, такими как __proto__и constructor.

Ключевой шаблон здесь заключается в том, что символы обеспечивают четкое разделение между данными пользователя и данными программы в объектах. Поскольку символы не могут быть представлены в JSON, нет риска передачи данных в Express API с ненадлежащим свойством Symbol.iterator. В объектах, которые смешивают пользовательские данные со встроенными функциями и методами, например в моделях Mongoose, вы можете использовать символы, чтобы гарантировать, что пользовательские данные не конфликтуют со встроенными функциями.

Закрытые свойства

Поскольку нет двух одинаковых символов, символы являются удобным способом имитации закрытых свойств в JavaScript. Символы не отображаются в Object.keys(), и поэтому, если вы явно не export символ, никакой другой код не может получить доступ к этому свойству, если вы явно не пройдете функцию Object.getOwnPropertySymbols().

Символы также удобны для закрытых свойств, потому что они не отображаются в выходных данных JSON.stringify(). В частности, JSON.stringify() игнорирует ключи и значения символов.

Что дальше?

Символы являются отличным инструментом для представления внутреннего состояния объектов, гарантируя, что пользовательские данные остаются отделенными от состояния программы. С использованием символов больше нет необходимости в соглашениях, таких как префиксирование свойств состояния программы с помощью ‘$’. Поэтому в следующий раз, когда вы установите для свойства объекта значение $$__internalFoo, подумайте об использовании вместо этого символа.

Автор: Valeri Karpov

Источник: //thecodebarbarian.com

Редакция: Команда webformyself.

Метки:

Похожие статьи:

Комментарии Вконтакте: