Исходный вопрос:
JSHint жалуется, когда мой JavaScript вызывает функцию, которая определена дальше по странице, чем ее вызов. Однако моя страница предназначена для игры, и никакие функции не вызываются до тех пор, пока все не будет загружено. Так почему же в моем коде фигурируют функции заказа?
РЕДАКТИРОВАТЬ: Думаю, я нашел ответ.
http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
Я внутри стону. Похоже, мне нужно провести ДРУГОЙ день, переупорядочивая шесть тысяч строк кода. Кривая обучения с javascript совсем не крутая, но очень длинная.
javascript
function
jslint
jshint
Крис Толуорти
источник
источник
Ответы:
tl; dr Если вы ничего не звоните, пока все не загрузится, все будет в порядке.
Изменить: для обзора, который также охватывает некоторые объявления ES6 (
let
,const
): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Scope_CheatsheetЭто странное поведение зависит от
Вот несколько примеров.
Это из-за того, что называется подъемом !
Есть два способа определения функций: объявление функции и выражение функции . Разница раздражает и минуты, так что давайте просто сказать , что это немного не то: Если вы пишете это как
function name() {}
, это заявление , и , когда вы пишете , какvar name = function() {}
(или анонимную функцию , назначенную к возвращению, и тому подобное), это выражение функции .Во-первых, давайте посмотрим, как обрабатываются переменные:
Теперь, как обрабатываются объявления функций :
В
var
ведомости «кидает» на создание вfoo
до самого верха, но не присваивает значение для нее еще. Далее следует объявление функции, и, наконец, ей присваивается значениеfoo
.А что насчет этого?
В начало перемещается только объявление of
foo
. Присваивание происходит только после вызоваbar
, где оно было до того, как все подъемы произошли.И напоследок для краткости:
А что насчет функциональных выражений ?
Так же , как и обычные переменные, первый
foo
будет объявлен в высшей точке сферы, то ему присваивается значение.Посмотрим, почему второй пример выдает ошибку.
Как мы видели ранее,
foo
поднимается только создание объекта , а присваивание происходит там, где оно появилось в «исходном» (не поднятом) коде. Когдаbar
вызывается, ему до этогоfoo
присваивается значение, поэтомуfoo === undefined
. Теперь в теле функцииbar
, как будто вы это делаетеundefined()
, возникает ошибка.источник
Основная причина заключается в том , что , вероятно , JSLint делает только один проход на файл , чтобы он не знает , что будет определять такую функцию.
Если вы использовали синтаксис оператора функций
На самом деле нет никакой разницы, где вы объявляете функцию (она всегда ведет себя так, как будто объявление находится в начале).
С другой стороны, если ваша функция была установлена как обычная переменная
Вы должны гарантировать, что не вызовете его перед инициализацией (на самом деле это может быть источником ошибок).
Поскольку переупорядочивание тонны кода сложно и само по себе может быть источником ошибок, я предлагаю вам поискать обходной путь. Я почти уверен, что вы можете заранее сообщить JSLint имя глобальных переменных, чтобы он не жаловался на необъявленные вещи.
Оставьте комментарий в начале файла
Или вы можете использовать для этого текстовое поле. (Я также думаю, что вы можете передать это в аргументах внутренней функции jslint, если можете вмешиваться в нее.)
источник
Слишком много людей продвигают произвольные правила написания JavaScript. Большинство правил - полная чушь.
Подъем функций - это особенность JavaScript, потому что это хорошая идея.
Когда у вас есть внутренняя функция, которая часто является утилитой внутренних функций, добавление ее в начало внешней функции является приемлемым стилем написания кода, но у него есть недостаток, заключающийся в том, что вам нужно прочитать детали, чтобы понять, что внешняя функция делает.
Вы должны придерживаться одного принципа во всей кодовой базе: помещайте частные функции первыми или последними в модуле или функции. JSHint хорош для обеспечения согласованности, но вы должны АБСОЛЮТНО настроить .jshintrc в соответствии со своими потребностями, а НЕ подгонять исходный код под дурацкие концепции кодирования других людей.
Один стиль кодирования, который вы можете встретить на практике, вам следует избегать, потому что он не дает вам никаких преимуществ и дает только возможные неудобства при рефакторинге:
Это именно то, чего следует избегать при подъеме функций. Просто выучите язык и используйте его сильные стороны.
источник
Поднимается только объявление функции, а не выражение функции (присвоение).
источник