Я признаю, что искал это. Я не думаю, что понял бы это так легко, если не сказать больше. http://kangax.github.com/nfe/#spidermonkey-peculiarity
Чтобы понять проблему, необходима семантика выражений именованных функций. Чтобы процитировать ссылку, «идентификатор выражения именованной функции доступен только для локальной области видимости функции». Конкретно это означает:
var fn = function aNamedFunction() {
typeof aNamedFunction; // "function"
};
typeof aNamedFunction; // "undefined"
Чтобы реализовать это поведение, SpiderMonkey и другие механизмы JS создают фиктивный фрейм среды между родительским фреймом (т. Е. Областью действия, в которой определяется функция) и внутренним фреймом функции, который создается каждый время, когда функция вызывается. Этот фиктивный фрейм построен, как если бы был вызван new Object()
, и содержит отображение из aNamedFunction
в сам объект функции.
В примере кода вопроса x
разрешается, сначала посмотрев в самый внутренний фрейм вызова функции. Поскольку тело функции не объявляет var x;
, оно не найдено, и интерпретатор проверяет кадр на один уровень вверх, который является фиктивным кадром. Поскольку фиктивный фрейм был создан new Object()
(или чем-то семантически эквивалентным), поиск x
в фиктивном фрейме будет проходить по цепочке прототипов, как и для любого другого объекта JavaScript. Таким образом, он ищет Object.prototype
, находит строку 'foo'
, связанную с x
, и возвращает ее.
Слава Богу, за последовательное лексическое определение ES5.
Альтернативное чтение: http://dmitrysoshnikov.com/ecmascript/chapter-5-functions/#nfe-and-spidermonkey