Подтвердить что ты не робот

Закрытие компилятора Предупреждение `опасное использование глобального объекта?

Уважаемые люди, 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. Как мне улучшить/решить этот код?

мерси!

4b9b3361

Ответ 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