Закрытие компилятора Предупреждение `опасное использование глобального объекта?
Уважаемые люди, Closure Compiler дает эти предупреждения в расширенном режиме, подчеркивая {this.
JSC_USED_GLOBAL_THIS: опасное использование глобального объекта по строке 200 символов 33
hovers[i4].onfocus = function() {this.className += "Hovered";}
JSC_USED_GLOBAL_THIS: опасное использование глобального объекта в строке 201 символа 32
hovers[i4].onblur = function() {this.className = this.className.replace(/Hove...
JSC_USED_GLOBAL_THIS: опасное использование глобального объекта по строке 201 символа 49
hovers[i4].onblur = function() {this.className = this.className.replace(/Hove...
JSC_USED_GLOBAL_THIS: опасное использование глобального объекта в строке 218 символа 38
buttons[i5].onmouseover = function() {this.className += "Hovered";}
Q1. Что в этом опасно?
Q2. Должен ли я изменить это?
Q3. Как мне улучшить/решить этот код?
мерси!
Ответы
Ответ 1
"this" может иметь разное значение в разных контекстах, поэтому он точно сообщает об этом.
Вместо этого вы можете использовать закрытие:
Вместо
hovers[i4].onfocus = function() {this.className += "Hovered";}
имеет:
hovers[i4].onfocus = function(self)
{
return function() {self.className += "Hovered";}
}(hovers[i4])
Ответ 2
Если вы знаете тип переменной "this", вы можете объявить ее с помощью JsDoc, чтобы остановить компилятор от жалобы:
hovers[i4].onfocus =
/** @this {Element} */
function() {this.className += "Hovered";}
Предостережение: это, однако, предполагает, что вы знаете тип переменной "this". Это может быть не так просто, как кажется. Например:
foo.doSomething = function(x) { this.bar = x; }
foo.doSomething("Hello");
Вы бы знали, что "this" в doSomething
относится к foo
. Однако, если вы используете расширенный режим компилятора Closure, компилятор может "сгладить" пространство имен foo
, и в итоге вы получите:
a = function(x) { this.b = x }
a("Hello");
когда foo.doSomething
"сплющено" к одной глобальной переменной a
. В этом случае переменная "this", очевидно, указывает на глобальный объект! Ваш код сломается!
Следовательно, компилятор Closure совершенно непреклонен, предупреждая вас не использовать "this" в функциях, которые можно сгладить. Вы можете использовать "this" в конструкторах и прототипах без этого предупреждения.
Чтобы решить эту проблему, лучше избегать использования "this" с помощью самого пространства имен:
foo.doSomething = function(x) { foo.bar = x; }
foo.doSomething("Hello");
Ответ 3
Просто добавьте пример того, что @marcinkuzminski добавил комментарий к @stephen Chung answer
/**
* Model for ListBox
*
* @constructor <-- add this to remove the warning
*/
MyProject.ListBoxModel = function ( data ){
this.data_ = data || {}; /* this gives warning */
};
Источник: https://developers.google.com/closure/compiler/docs/js-for-compiler