This translation is incomplete. Please help translate this article from English.
Это экспериментальная технология, часть предложения Harmony (ECMAScript 6).
Поскольку спецификация этой технологии ещё не стабилизировалась, проверьте таблицу совместимости её использования в различных браузерах. Также обратите внимание, что синтаксис и поведение экспериментальной технологии могут быть изменены в будущих версиях браузеров в соответствии с изменениями в спецификации.
Сводка
Символ (анг. Symbol) — это уникальный и неизменяемый тип данных, который может быть использован как идентификатор для свойств объектов. Символьный объект (анг. symbol object) — это объект-обёртка (англ. wrapper) для символа primitive data type.
Синтаксис
Symbol([описание])
Параметры
-
descriptionНеобязательный - Необязательный, строка. Описание символа, которое может быть использовано во время отладки, но не для доступа к самому символу.
Описание
Чтобы создать новый символьный примитив, достаточно написать Symbol(), указав по желанию строку в качестве описания этого символа:
var sym1 = Symbol();
var sym2 = Symbol("foo");
var sym3 = Symbol("foo");
Код выше создает три новых символа. Заметьте, что Symbol("foo") не выполняет приведение (англ. coercion) строки "foo" к символу. Это выражение создает каждый раз новый символ:
Symbol("foo") === Symbol("foo"); // false
Код ниже с оператором new бросит исключение TypeError:
var sym = new Symbol(); // TypeError
Это удерживает разработчиков от непосредственного создания объекта-обёртки Symbol вместо нового символьного значения. Непосредственное создание объекта-обёртки для примитивных значений не поддерживается, начиная с версии ECMAScript 6. Тем не менее, существующие объектные обёртки, такие как new Boolean, new String и new Number все еще могут быть созданы из соображений обратной совместимости.
А если вам действительно необходимо обернуть символ в объект, вы можете использовать функцию Object():
var sym = Symbol("foo");
typeof sym; // "symbol"
var symObj = Object(sym);
typeof symObj; // "object"
Разделяемые символы в глобальном символьном реестре
Приведенный выше синтаксис, использующий функцию Symbol(), не создаст глобальный символ, который был бы доступен в любом месте вашего кода. Для создания символов, доступных во всех файлах и в окружении, подобном глобальному, используйте методы Symbol.for() и Symbol.keyFor(), чтобы задать или получить символ из глобального символьного реестра.
Поиск символьных свойств у объектов
Метод Object.getOwnPropertySymbols() возвращает массив символов и позволяет получить символьные свойства конкретного объекта. Следует заметить, что при инициализации объекты не получают символьных свойств, так что этот массив будет пуст, пока вы не зададите ему какое-либо символьное свойство.
Свойства
-
Symbol.length - Содержит длину, всегда равную 1 (единице).
-
Symbol.prototype -
Содержит прототип конструктора
Symbol.
Распространенные символы
В добавок к вашим собственным символам, JavaScript имеет несколько встроенных символов, представляющих внутренние механизмы языка, которые не были доступны разработчикам в версиях ECMAScript 5 и более ранних. Эти символы доступны посредством следующих свойств:
- Symbol.hasInstance
-
Обозначается @@hasInstance. Метод, определяющий, распознает ли конструктор некоторый объект как свой экземпляр. Используется оператором
instanceof. - Symbol.isConcatSpreadable
-
Обозначается @@isConcatSpreadable. Булево значение, показывающее, должен ли объект быть сведен к плоскому представлению (англ. flatten) в виде массива его элементов функцией
Array.prototype.concat(). - Symbol.isRegExp
- Обозначается @@isRegExp. Булево значение, показывающее, может ли объект использоваться в качестве регулярного выражения.
- Symbol.iterator
-
Обозначается @@iterator. Метод, возвращающий итератор по умолчанию для объекта. Используется конструкцией
for...of. - Symbol.toPrimitive
- Обозначается @@toPrimitive. Метод, преобразующий объект в примитив (примитивное значение).
- Symbol.toStringTag
-
Обозначается @@toStringTag. Строковое значение, используемое в качестве описания объекта по умолчанию. Используется функцией
Object.prototype.toString() - Symbol.unscopables
- Обозначается @@unscopables. Массив строковых имен свойств. Позволяет скрыть свойства от инструкции with (прежде всего для обратной совместимости).
Методы
-
Symbol.for(key) - Ищет ранее созданный разделяемый символ по заданному ключу и возвращает его, если он найден. В противном случае создается новый разделяемый символ для данного ключа в глобальном реестре символов.
-
Symbol.keyFor(sym) - Получает по разделямому символу его ключ из глобального реестра символов.
Прототип Symbol
Все символы наследуют от Symbol.prototype.
Свойства
Symbol.prototype.constructor- Returns the function that created an instance's prototype. This is the
Symbolfunction by default.
Методы
Symbol.prototype.toSource()- Returns a string containing the source of the
Symbolobject. Overrides theObject.prototype.toSource()method. Symbol.prototype.toString()- Returns a string of containing the description of the Symbol. Overrides the
Object.prototype.toString()method. Symbol.prototype.valueOf()- Returns the primitive value of the
Symbolobject. Overrides theObject.prototype.valueOf()method.
Примеры
Использование оператора typeof с символами
Оператор typeof позволяет различить символ.
typeof Symbol() === 'symbol'
typeof Symbol('foo') === 'symbol'
typeof Symbol.iterator === 'symbol'
Преобразование типов с символами
Следующее необходимо помнить при преобразовании типа символов.
- При попытке конвертировать символ в число, будет брошено исключение
TypeError(напр.,+symилиsym | 0). - Результатом нестрогого сравнения,
Object(sym) == sym, будетtrue. Symbol("foo") + "bar"бросает исключениеTypeError(невозможно преобразовать символ в строку). Это удерживает разработчика от, к примеру, случайного создания строкого поля у объекта из символа.- Более "безопасный" вызов
String(sym)работает с символами как вызовSymbol.prototype.toString(). Заметьте, что в то же времяnew String(sym)бросит исключение.
Символы и конструкция for...in
Символы невидимы при итерации for...in. В дополнение к этому, Object.getOwnPropertyNames() не вернет символьные свойства объекта. Тем не менее, их можно получить с помощью Object.getOwnPropertySymbols().
var obj = {};
obj[Symbol("a")] = "a";
obj[Symbol.for("b")] = "b";
obj["c"] = "c";
obj.d = "d";
for (var i in obj) {
console.log(i); // выведет "c" и "d"
}
Символы и JSON.stringify()
JSON.stringify() игнорирует свойства с символьными именами:
JSON.stringify({[Symbol("foo")]: "foo"});
// '{}'
Подробности см. JSON.stringify().
Объекты-обертки для Symbol в качестве имен свойств
Когда объект-обёртка символа используется в качестве имени свойства, этот объект сводится к символу, который он оборачивает:
var sym = Symbol("foo");
var obj = {[sym]: 1};
obj[sym]; // 1
obj[Object(sym)]; // снова 1
Спецификации
| Спецификация | Статус | Комментарий |
|---|---|---|
| ECMAScript 6 (ECMA-262) Определение 'Symbol' в этой спецификации. |
Кандидат в рекомендации | Initial definition. |
Поддержка браузерами
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Basic support | 38 | 33.0 (33.0) [1] | Нет | 25 | Нет |
| Symbol.iterator (@@iterator) | 38 | Нет | Нет | 25 | Нет |
| Symbol.unscopables (@@unscopables) | 38 | Нет | Нет | 25 |
Нет
|
| Other well-known symbols | Нет | Нет | Нет | Нет | Нет |
| Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | Нет | 38 | 33.0 (33.0) | Нет | 25 | Нет |
| Symbol.iterator (@@iterator) | Нет | 38 | 33.0 (33.0) | Нет | 25 | Нет |
|
Symbol.unscopables (@@unscopables)
|
Нет | 38 | ? | Нет | 25 | Нет |
| Other well-known symbols | Нет | Нет | Нет | Нет | Нет | Нет |
[1] На данный момент символы доступны только на канале Nightly (ошибка 1041631).