Где хранится запись неизменяемой привязки идентификатора в выражении именованной функции в JavaScript?

Недавно я столкнулся с некоторыми интересными фактами о выражениях именованных функций (NFE). Я понимаю, что к имени функции NFE можно получить доступ в теле функции, что делает рекурсию более удобной и спасает насarguments.callee, И имя функции не доступно вне тела функции. Например,

var foo = function bar() {
    console.log(typeof bar);
}; 

typeof foo; // 'function'
typeof bar; // 'undefined', inaccessible outside the NFE
foo(); // 'function', accessible inside the NFE

Это хорошо документированная функция, и у Кангаксасообщение про НФЭ и упомянул это явление там. Что меня больше всего удивляет, так это то, что имя функции NFE не может быть связано с другими значениями в теле функции. Например,

(function foo() {
    foo = 5;
    alert(foo);
})(); // will alert function code instead of 5

В приведенном выше примере мы попытались повторно привязать идентификаторfoo с другим значением5, Но это не удалось! И я обратился к ES5 Spec и обнаружил, что запись неизменяемой привязки была создана и добавлена ​​в записи среды лексической среды при создании NFE.

Проблема в том, что когда NFE ссылается на собственное имя функции внутри тела функции, имя было разрешено каксвободная переменная, В приведенном выше примереfoo упоминается внутри NFE, но не является ни формальным параметром, ни локальной переменной этой функции. Так что это свободная переменная и ее запись привязки может быть разрешена через свойство [[scope]] NFE.

Итак, учтите это, если у нас есть другой идентификатор с таким же именем во внешней области видимости, кажется, что существует некоторый конфликт. Например,

var foo = 1;
(function foo() {
    alert(foo);
})(); // will alert function code rather than 1
alert(foo); // 1

Когда мы выполняем NFE,свободная переменная foo был преобразован в функцию, с которой он связан. Но когда контроль выходит из контекста NFE,foo была решена как локальная переменная во внешней области видимости.

Итак, мой вопрос заключается в следующем:

Где хранится запись неизменяемой привязки имени функции?Как получилось название функцииfoo перевешиватьvar foo = 1 когда разрешено внутри НФЭ? Хранятся ли их обязательные записи в одной и той же лексической среде? Если так, то как?Что стоит за феноменом, который называют функциейfoo доступен внутри, но невидим снаружи?

Может кто-нибудь пролить свет на это с ES5 spec? Я не нахожу много дискуссий в Интернете.

Ответы на вопрос(1)

Ваш ответ на вопрос