Расширенная оптимизация компилятора google-close искажает navigator.battery.level, вызывая TypeError

Я использую ClojureScript для получения уровня заряда батареи с помощью:

 navigator.battery.level

Что отлично работает при использовании простой оптимизации и оптимизации пробелов. Но при использовании режима расширенной оптимизации приведенное выше превращается в:

navigator.hd.rd

И вызывает TypeError, поскольку navigator.hd не определен.

Как я могу это исправить?

ИЗМЕНИТЬ:

Исправлено благодаря ответу ниже. Хотя в ClosureScript мне пришлось бы делать какие-то неприятные, вложенные, агеты... Так что я придумал это:

(defn jget [jobject & props]    
(loop [obj jobject 
       p (map name props)]
    (if (not (empty? p))            
        (let [prop (aget obj (first p))]
            (recur prop (rest p)))
    obj)))

затем назвал это так:

(jget js/navigator :battery :level)

Если для этого уже есть инструменты, может кто-нибудь, пожалуйста, дайте мне знать.


person jdoig    schedule 17.03.2013    source источник


Ответы (2)


Другое решение — написать файл externs, который представляет собой файл JavaScript, содержащий ссылки на все объекты и методы, имена которых вы хотите сохранить. В этом случае файл JS будет выглядеть примерно так:

//resources/externs/navigator.js
navigator = {}
navigator.battery = {}
navigator.battery.level = function(){};

И вы бы назвали это в параметрах компилятора ClojureScript следующим образом:

:externs ["resources/externs/navigator.js"]

Подобно предложенному Sirko решению, это предотвратит искажение имени navigator.battery.level компиляцией в расширенном режиме.

person levand    schedule 18.03.2013
comment
Спасибо, Левланд. Если я хочу автоматизировать генерацию внешних файлов, можно ли с уверенностью сказать, что учитывая строку: ‹1›.‹2›.‹3› например: navigator.battery.level Имя файла должно = ‹1›, От ‹1› до ‹1›.‹n-1› всегда следует назначать = {}, а ‹1›.‹..›.‹n› всегда следует назначать = function(){}. - person jdoig; 18.03.2013
comment
@jdoig Автоматическое создание внешнего объекта в целом не так просто. Приведенный выше внешний вид не содержит никакой информации о типах или вложенных типах. - person Chad Killingsworth; 18.03.2013

Использовать

 navigator['battery']['level']

это сохранит наименование.

Компилятор закрытия чаще всего переименовывает переменные в точечной нотации (например, navigator.battery), но сохраняет те, которые ему известны или которые используют скобочную нотацию (например, navigator['battery']).

person Sirko    schedule 17.03.2013
comment
Верный. Closure-compiler в настоящее время не имеет внешних модулей для API состояния батареи. - person Chad Killingsworth; 18.03.2013