Что такое "глобальный реестр символов"?

var sym = Symbol();

и window['sym'] которые уже глобальный масштаб.

но MDN говорит:

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

sym уже находится в глобальной области в браузере с вышеуказанным синтаксисом объявления.

Что такое глобальный регистр символа?

каждый html-документ связан с

3 ответов


var sym = Symbol();

создает новое свойство sym в словарь(window), который находится в глобальной области, где значение может быть доступно как window['sym'].

Ну, нет. Он создает символ и присваивает его локальная переменная имени sym. Только если вы выполняете этот код в глобальной области (чего вы обычно не делаете, для модульности), он создает свойство на глобальном объекте вашей области (среда js). Обратите внимание, что этот глобальный объект не всегда window как на веб-страницах, это зависит от вашей среды.

что такое глобальный регистр символа?

это реестр (думаю: словарь) для символов, которые вы можете получить доступ через строковый ключ. И "глобальный" в этом случае означает даже более глобальный чем глобальная область, глобальный реестр символов охватывает все области вашего движка. В браузере веб-страница, iframe и web worker будут иметь свои собственные realm с собственными глобальными объектами, но они могут обмениваться символами через этот глобальный реестр.

и это совместное использование является именно целью. Если бы вы иначе поставили

var sym1 = Symbol("shared");

var sym2 = Symbol("shared");

в двух местах, затем sym1 !== sym2. Если у вас есть общий объект, используйте символs как ключи свойств создадут два разных свойства. Если, однако, вы делаете

var sym1 = Symbol.for("shared");

var sym2 = Symbol.for("shared");

затем sym1 === sym2 и когда вы используете его, вы всегда будете получать одно и то же свойство.

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


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

в вашем собственном приложении вы можете решить, что некоторые типы объектов будут иметь определенные свойства, доступные через некоторый символ. Весь ваш код может найти эти символы через Symbol.for():

var SPECIAL_PROPERTY = Symbol.for("mySpecialProperty");
// ...
var specialVal = someObject[SPECIAL_PROPERTY];

поскольку реестр является глобальным, он работает независимо от области или единицы компиляции.

путем создания части реестра среды выполнения, такой как Node.js может использовать механизм символов для расширения объектов, не опасаясь возникновения проблем для устаревшего кода. Например, если Node хочет сделать так, чтобы вы могли узнать, сколько памяти используется объект, они могут изобрести символ, поместить его в реестр и документировать раздел реестра. Любой код может тогда используйте это:

var objectSize = myObject[Symbol.for("memory_use")];

(это полностью составлено; это может вообще не иметь смысла для Node делать эту конкретную вещь.) Из-за того, как символы работают как ключи свойств, код, который не знает об этом, не будет испытывать никаких странных проблем, если объекты, которыми он манипулирует, внезапно начнут носить это дополнительное свойство.

(конечно, пространство имен самого реестра символов - это просто пространство имен, поэтому столкновения должны быть рассмотрены там в значительной степени точно так же мы имеем дело с коллизиями имен в window "объект".)


Глобальный реестр символов существует во всех iframes в окне. (Поскольку символы не могут передаваться через рабочих, нет наблюдаемой концепции его идентичности между рабочими, исключая существование побочных проверок, например,память зондирующего.)

<script>
document.head.appendChild(document.createElement('iframe'))
.src=`javascript:
  alert(parent.Symbol===Symbol) /*false*/
  ,alert(parent.Symbol.for('a') === Symbol.for('a')) //true
`
</script>

Symbol.for не сильно отличается от реализации собственного кэша с помощью ссылки на объект. Он просто встроенный и поэтому более удобный. Вместо Symbol.for('a'), вы можете просто do:

obj['a']? obj['a'] : obj['a'] = Symbol()`

.и поддерживать ref к obj.

на самом деле, поскольку javascript не предоставляет API для удаления символов в глобальном реестре, его полезно сделать это вручную-кэширование, если вам нужно вручную управлять памятью реестра.