2012-04-29 2 views
2

My webapp основан на общем скрипте, где я определяю общие функции и глобальную переменную и динамически загружаемые скрипты, которые обрабатывают их. Пока единственный способ экспортировать глобальную переменную - заменить любое событие на window["myGlobalVar"], но я считаю это очень уродливым. Есть ли лучший способ сделать это?Компилятор Javascript Closure -Exporting global variables

Вот иллюстрация

// commonscript.js before compilation 
function incrementVariable() {window["myGlobalVar"]++;} 
window["incrementVariable"] = incrementVariable; 
window["myGlobalVar"] = 0; 

и в другом сценарии

alert(myGlobalVar); // <= alerts 0 
incrementVariable(); 
alert(myGlobalVar); // <= alerts 1 

Ищу способ использовать непосредственно myGlobalVar в обоих файлах, потому что это было бы более элегантно. Тем не менее, мне нужно было бы установить window["myGlobalVar"] указателю, а не копии объекта, и я не уверен, как это сделать на простых типах.

Возможно ли это? Является ли инкапсуляция myGlobalVar в Object единственным способом?

Большое спасибо за ваши огни.

+1

Экспорт API всегда довольно неуклюжий в Closure.В этом случае лучше сделать 'myGlobalVar' частной обфускационной переменной и предоставить функцию GetMyGlobalVar. Таким образом, по крайней мере, вы уменьшаете экземпляры 'window [" myGlobalVar "]' везде в вашем коде. –

+0

Экспорт ваших функций может быть проще, если вы используете глобальный объект пространства имен: 'window [" mynamespace "] = {" incrementVariable ": incrementVariable," getMyGlobalVar ": function() {return myGlobalVar}};' Тогда вы можете сделать: ' оповещение (mynamespace.getMyGlobalVar()); mynamespace.incrementVariable(); ... ' –

+0

Спасибо, я подумал об этом, и я понял, насколько неудобно использовать глобальные переменные. Я поеду для функций getter и setter, которые предлагают гораздо больше гарантии по сравнению с глобальными. Я также предположил, что инкапсуляция в «Object» также не очень велика. У меня была бы такая же проблема с членами объекта, имена которых были бы запутаны. Мне все равно нужен геттер и сеттер. –

ответ

7

Новый ответ

Closure-компилятор поддерживает @nocollapse аннотацию, который предотвращает свойство от разваливались к глобальной переменной. Это позволяет изменять свойство при экспорте.

@nocollapse не блокирует переименование - вам все равно необходимо экспортировать свойство, чтобы выполнить это.

@nocollapse в настоящее время поддерживается только при компиляции из источника. Он будет включен в следующий выпуск - это версии ПОСЛЕ релиз v20150315.

Старый Ответ

@expose теперь осуждается. Компилятор предупредит о любом использовании @expose

Существует новое, но до сих пор недокументированное, annoatation: @expose. Эта отдельная аннотация будет экспортировать свойство и предотвратить его свертывание с конструктора. Это звучит как идеальная подгонка вашей ситуации, но для этого вам потребуется, чтобы ваша переменная была свойством объекта.

Однако, используйте с осторожностью. Любые свойства, имеющие @expose, не будут переименованы и не будут удалены как мертвый код. Это делает его особенно проблематичным для использования писателями библиотеки javascript.

0

Если вы хотите иметь переменную, которая не переименовываются, просто создать файл с именем, например props.txt со следующим содержанием:

myGlobalVar:myGlobalVar 

Затем при компиляции кода, добавьте аргумент командной строки: --property_map_input_file props.txt

Ваша переменная не будет переименована и доступна для всех сценариев, если она не оптимизирована. Кроме того, если вы не объявите его вообще (так что вы опустите var myGlobalVar), он не будет переименован или удален.

+0

Хотя компилятор пытается почеркнуть имена на карте ввода свойств, это не требуется. Исходные решения - правильное решение. –

Смежные вопросы