ВНИМАНИЕ - опасное использование глобального объекта - PullRequest
8 голосов
/ 27 октября 2010

В Google Closure Compiler я получаю предупреждение

ПРЕДУПРЕЖДЕНИЕ - опасное использование глобального объекта

Вот пример. Строка ошибки и смещение относятся к началу слова this

function aToggle() {
  if(shown)
    toggle.show()
  else
    toggle.hide()
  $(this).text(shown ? 'Click to hide' : 'Click to show')
  shown = !shown
}
link.onclick = aToggle

Я бы просто изменил его на анонимный метод, но я повторно использую aToggle в другом месте файла, поэтому его нужно назвать.

Я мог бы пометить aToggle как /**@constructor*/ - но это не конструктор. Есть ли другая аннотация, которую я могу использовать для устранения этого предупреждения, или я застрял между пометкой его как конструктора или появлением множества бесполезных предупреждений?

Ответы [ 3 ]

13 голосов
/ 29 октября 2010

Редактировать : я читал Closure: полное руководство, и я только что понял, что вы можете просто добавить аннотацию /** @this {Element} */ перед обработчиком событий, чтобы сделать Closure Compiler хватит жаловаться.

См. Справочное руководство по Closure Compiler . Закрывающий компилятор выдает это предупреждение, когда вы используете this внутри функции, которая не аннотирована /** @constructor */ или не входит в prototype класса. Компилятор предполагает, что вы никогда не будете использовать this, когда функция вызывается в контексте другого объекта (что и делают обратные вызовы событий).

Некоторые места, которые вам, возможно, придется изменить, чтобы компилятор Closure перестал жаловаться с этим предупреждением:

  • Не используйте link.onclick = ... напрямую, потому что вы должны связываться с this и e || window.event. Вместо этого используйте jQuery для переноса обработчика событий, поскольку объект события jQuery имеет e.currentTarget.
  • Если вы используете this в пределах jQuery.each, замените this вторым параметром вашей функции. Например, jQuery.each([1, 2, 3], function(i, val) { ... val ... };.
1 голос
/ 28 октября 2010

Во-первых, вы, вероятно, делаете это неправильно. : -)

@ У Яна была правильная идея. Но вы, вероятно, должны пойти со следующим:

(function(){
    var toggle = $("#toggle");
    $("#yourLinksID, .orClassName").click(function(e) {
        var shown = toggle.toggle().is(":visible");
        $(this).html(shown ? "Click to hide" : "Click to show");
        e.preventDefault();
    });
}());

и при компиляции:

Используйте следующий внешний файл jQuery, который сообщает Closure Compiler, что делает в jQuery: http://code.google.com/p/closure-compiler/source/browse/trunk/contrib/externs/jquery-1.4.3.externs.js

Если вы просто хотите, чтобы предупреждающее сообщение исчезло, замените this на link.

1 голос
/ 27 октября 2010

Я не очень хорошо знаю JQuery, но я думаю, что вы можете использовать что-то вроде:

function aToggle(event) {
  if(shown) {
    toggle.show();
  } else {
    toggle.hide();
  }
  $(event.target).text(shown ? 'Click to hide' : 'Click to show');
  shown = !shown;
}

$(link).bind('click', aToggle);

, где вы извлекаете выбранную цель из универсального объекта события кросс-браузера.

РЕДАКТИРОВАТЬ: в качестве совета, используйте { } вместе с if else и используйте точки с запятой, не полагайтесь на свой браузер, чтобы сделать это за вас.

Чтобы наилучшим образом использовать инструменты закрытия, этоРекомендуется использовать библиотеку замыканий в сочетании с компилятором (хотя и не обязательно)

...