Почему расположение выражения функции не имеет значения в узле js?
В JavaScript при использовании выражения функции (например, var myFunc = function() {...}
), как и любое другое объявление переменной, вы должны определить переменную перед ее использованием. Например, следующий пример не будет работать (приведет к Uncaught TypeError: myFunc is not a function
):
var myVar = myFunc();
var myFunc = function() {
// code here...
}
Однако в моем файле routs/index.js проекта js узла у меня есть следующий код (очевидно, сокращенно):
var router = express.Router();
.
.
.
router.post('/', function(req, res) {
...
...
var myVar = myFunc(); // WORKS!
...
...
}
var myFunc = function() {
...
}
myFunc
переменная объявляется после того, как она используется, поэтому не должно ли это вызвать ошибку?
1 ответ
Есть два аспекта этого:
Почему обратный вызов может быть передан
router.post
получить доступ кmyFunc
переменная, когда декларация переменной находится ниже ее в коде?Почему обратный вызов может быть передан
router.post
получить доступ к функции, назначенной дляmyFunc
переменная, когда она не присваивается переменной до тех пор, пока она не будет указана в коде?
Сначала мы будем иметь дело с переменной, затем мы будем иметь дело с ее значением (функция, которую мы назначаем ей):
Переменная myFunc объявляется после ее использования, поэтому не должно ли это выдать ошибку?
Было бы если var
не были подняты. Но var
поднят. Поэтому, когда ваш модуль загружен, сначала движок JavaScript просматривает его, чтобы найти все объявления переменных и объявлений функций, обрабатывает их, а затем выполняет пошаговый код в вашем модуле.
Например, для движка JavaScript ваш модуль на самом деле выглядит так:
var router = undefined;
var myFunc = undefined;
router = express.Router();
.
.
.
router.post('/', function(req, res) {
var myVar = undefined;
...
...
myVar = myFunc(); // WORKS!
...
...
}
myFunc = function() {
...
}
Подробнее об этом в моем маленьком анемичном блоге: Бедный неправильно var
Почему расположение выражения функции не имеет значения в узле js?
Это делает. Единственная причина, по которой вы не столкнетесь с проблемами, заключается в том, что myFunc
не используется до тех пор, пока вы не перезвоните router.post
вызывается после того, как был запущен код области видимости верхнего уровня вашего скрипта модуля (включая создание выражения myFunc
).
Например, что происходит:
Подготовительный материал (создание Vars
router
а такжеmyFunc
и установив ихundefined
)express.Router
вызов, который назначает новое значениеrouter
Призыв к
router.post
, передавая, но не вызывая функцию обратного вызоваСоздание функции, которая присваивает новое значение
myFunc
Позже, когда приходит запрос, вызывается обратный вызов, к которому времени
myFunc
был создан (и доступен, потому что обратный вызов является закрытием в контексте, гдеmyFunc
объявлен)
Это аналогично этому:
setTimeout(function() {
var myVar = myFunc();
}, 0);
var myFunc = function() {
// code here...
}
Первый setTimeout
вызывается, то функция создается и назначается myFunc
затем вызывается функция обратного вызова и вызывает функцию через myFunc
,