Почему расположение выражения функции не имеет значения в узле 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 ответ

Решение

Есть два аспекта этого:

  1. Почему обратный вызов может быть передан router.post получить доступ к myFunc переменная, когда декларация переменной находится ниже ее в коде?

  2. Почему обратный вызов может быть передан 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).

Например, что происходит:

  1. Подготовительный материал (создание Vars router а также myFunc и установив их undefined)

  2. express.Router вызов, который назначает новое значение router

  3. Призыв к router.post, передавая, но не вызывая функцию обратного вызова

  4. Создание функции, которая присваивает новое значение myFunc

  5. Позже, когда приходит запрос, вызывается обратный вызов, к которому времени myFunc был создан (и доступен, потому что обратный вызов является закрытием в контексте, где myFunc объявлен)

Это аналогично этому:

setTimeout(function() {
    var myVar = myFunc();
}, 0);

var myFunc = function() {
    // code here...
}

Первый setTimeout вызывается, то функция создается и назначается myFunc затем вызывается функция обратного вызова и вызывает функцию через myFunc,

Другие вопросы по тегам