2013-08-26 3 views
3

У меня есть длинный сценарий, красиво завернутый в (function() {/.../})(), чтобы избежать загрязнения всех видов. Он на 100% печатается с нулевым предупреждением.Почему компилятор Google Closure добавляет переменную в глобальное пространство имен, когда исходное пространство имен пусто?

Я узнал, что компилятор Google Closure начинается с переопределения i и j в глобальном пространстве имен, которое кажется ненужным и опасным, особенно если я компилирую скрипт, который имеет нулевые помехи в пространстве имен. (скомпилированный скрипт начинается с var i=null,j=!1;, по соображениям компактности, я считаю).

Я могу придумать, как обернуть его, используя --output_wrapper, но я не могу придумать, почему Google загрязнит пространство имен, подобное этому.

Есть ли какие-либо?

+0

[Это похожий пример] (https://groups.google.com/forum/#!topic/closure-compiler-discuss/ZLrYebO3DDs) – abc123

+0

возможно дубликат [Как предотвратить Closure Compiler от переименования " true "," false "и" null "] (http://stackoverflow.com/questions/4618571/how-to-prevent-closure-compiler-from-renaming-true-false-and-null) – Alexander

+0

Не совсем, Я уже знал об обертке, о которой я упоминаю в своем посте. Я искал причину добавления глобальной области, в то время как моя была пустой. Ответ, похоже, заключается в том, что компилятор Closure не поддерживает ли мой объем пустым или нет, он просто делает предположение, что он может его использовать. –

ответ

9

Компилятор ожидает, что ему задан Соответствующий JavaScript, чтобы не беспокоиться о столкновениях с другими скриптами. Поэтому он предполагает, что он может развернуть «ненужную» анонимную функцию.

От FAQ:

При использовании Advanced оптимизаций, Closure Compiler добавляет новые переменные в глобальном масштабе. Как я могу убедиться, что мои переменные не сталкиваются с другими скриптами на странице?

Режим расширенных оптимизаций Closure Compiler предполагает, что в глобальную область можно добавлять новые переменные.

В JavaScript часто применяется стандартная практика для переноса вашего кода в анонимную функцию, так что переменные не загрязняют глобальную область. Для компилятора Closure для этой цели есть флаг --output_wrapper. Вызывая его как --output_wrapper "(function() {%output%})();", он будет завершать ваш код в анонимной функции во время компиляции.

Пользователям Closure Compiler часто проще и проще выполнять эту упаковку во время компиляции, вместо того, чтобы писать анонимную оболочку функции в исходном исходном коде.

+0

Действительно. Подумав об этом, Closure никогда не стремился не загрязнять пространство имен. Поэтому компилятор не потрудился понять, решила ли я защитить область действия, и она добавит материал в глобальную область действия независимо от того, как я использую '--output_wrapper', который я буду все время с этого момента. –

+0

При компиляции с '--output_wrapper' в режиме' ECMASCRIPT5_STRICT', стоит упомянуть, что значение 'this' в анонимной оболочке должно быть привязано вручную к объекту' window': '(function() {% output%}) .call (окно) '. В противном случае 'this' не ссылается на глобальный объект в строгом режиме. –

+0

Обходной путь 'output_wrapper' для глобального загрязнения области Closure кажется значительно уступающим простой опции, чтобы сказать, чтобы он не загрязнял глобальную область ... И, действительно, он НЕ РЕШИЛ проблему во всех случаях. В моей ситуации у меня есть глобальные методы (фактически конструкторы для «типов»), которые скрыты оболочкой, препятствуя доступу со стороны внешнего JS и разбивая мою библиотеку :-( –