Почему имя функции внутри именованной функции в JavaScript больше не ссылается на саму функцию?

Рассмотрим следующую именованную функцию:

function f() {
    return f.apply(this, arguments);
}

Если вы вызываете эту функцию нормально, это приведет к переполнению стека, как и ожидалось. Не очень интересно Итак, давайте сделаем немного магии:

var g = f, f = alert;

Теперь, если вы позвоните f это будет просто alert первый аргумент. Однако если вы позвоните g это все еще будет alert первый аргумент. Что происходит? Не должен звонить g привести к переполнению стека?

Я понимаю, что внутри функции f (сейчас g) переменная f больше не связан с f, Это становится свободной переменной. Следовательно внутри f переменная f сейчас указывает на alert,

Почему это происходит? Я ожидаю, что имя функции внутри именованной функции всегда будет ссылаться на саму функцию. Я не жалуюсь. Это на самом деле довольно круто. Мне просто интересно.

2 ответа

Решение

Когда вы делаете:

var g = f

Это фактически так же, как:

var g = function () {
    return f.apply(this, arguments);
}

Тем не менее, так как вы переназначены f он больше не указывает на исходную функцию, теперь он указывает на alert, Похоже, он работает как задумано.

Как уже упоминалось в других ответах, это так, как задумано. По сути, кроме подъема, объявление делает это:

var f = function () {
    return f.apply(this, arguments);
}

То есть ценность f разрешается не в объявлении, а во время вызова функции. Вот почему вы видите то, что видите.

Но есть способ заставить его вести себя так, как вы хотите: использовать выражение с именованной функцией. Выражение именованной функции выглядит как объявление, но не потому, что функция объявлена ​​как выражение.

Например, в следующем:

var ff = function f () {
    return f.apply(this, arguments);
}

Значение f связан в декларации и будет неуязвимым для переназначения. В выражении именованной функции имя функции определяется только внутри выражения и поэтому ведет себя скорее как замыкание, а не как переменная.

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