Почему JSLint жалуется на неопределенную / подразумеваемую глобальную переменную? - PullRequest
4 голосов
/ 21 октября 2010

Я пытаюсь понять, почему JSLint жалуется на неявную глобальную переменную в следующем примере:

var TEST = (function () {
  var count = 0;

  function get_count() { 
    return add_one(); 
  }

  function add_one() {
    count += 1;
    return count;
  }

  return { 
    get_count: get_count
  };
}());

Запуск через JSLint выдает ошибку:

Проблема встрока 5, символ 12: «add_one» не определен.

А также:

Подразумеваемый глобальный: add_one 5

Вы перемещаете функцию add_one() до функции get_count(), ошибка исчезает.Однако с кодом, как указано выше, он не выдает никаких ошибок при запуске его в браузере.Кто-нибудь может объяснить, почему JSLint жалуется?

Спасибо!
Мэтт

Ответы [ 3 ]

11 голосов
/ 21 октября 2010

Это связано с тем, что JSLint использует Pratt Parser , анализатор сверху вниз, а не полноценный интерпретатор JavaScript. Если бы это было действительно истолковано, то это не дало бы вам этой ошибки.

add_one является подразумеваемым глобальным, потому что синтаксический анализатор еще не сталкивался с этой переменной, поэтому он предполагает, что окружающий код будет иметь эту переменную. Но, если вы перевернете его, то парсер уже наткнулся на переменную add_one, и это все персики и сливки: -)

Кстати, я заметил небольшую опечатку в вашей строке функции закрытия: }()); должно быть })();.

1 голос
/ 15 декабря 2010

Вы получаете * add_one не определено *, потому что JSLint считает, что выражения функций должны быть объявлены в правильном порядке, а для другой проблемы ("* подразумевается глобально: add_one 5 *") достаточно поместить комментарий, такой как / * globals add_one * / вверху вашего скрипта

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

Я изменяю порядок, в котором объявлены методы, это решит вашу проблему.Как уже упоминалось в другом ответе, некоторые синтаксические анализаторы JavaScript используют нисходящий подход к чтению кода, аналогично тому, как это делает язык программирования Си.Современные интерпретаторы и компиляторы используют двухпроходный подход.Первый проход - чтение / компиляция методов в память.Если он встречает какие-либо вызовы методов, о которых он не знает, он просматривает весь набор методов в памяти, чтобы определить, существует ли он.Я бы порекомендовал исправить порядок, потому что, хотя это может не вызывать проблем, он будет загружать метод в память быстрее с изменением.

...