Если я напишу это в глобальной области видимости:
(function(){})();
- анонимная функция, созданная, когда оператор выполняется и уничтожается сразу после выполнения оператора?
Как сказал t.niese, шансы, что двигатель полностью оптимизирует эту функцию.Итак, давайте предположим, что в нем есть некоторый код:
// At global scope
(function(){ console.log("Hi there"); })();
Движок не может гарантировать, что этот код не выдаст ошибку (например, если вы заменили console
чем-то другим), поэтомуЯ вполне уверен, что он не может просто вставить это.
Теперь ответ: Это зависит.
От уровня языка / спецификации, весь код в модуль компиляции (примерно: скрипт) анализируется при первой загрузке модуля компиляции.Затем эта функция создается, когда код достигает ее в пошаговом исполнении, выполняется после создания (что включает в себя создание контекста выполнения для вызова) и сразу же получает право на сборку мусора по завершении (вместе с контекстом выполнения)потому что ничто не имеет ссылки на это.Но это просто теория / высокоуровневая спецификация.
С точки зрения движка JavaScript:
- Функция анализируется перед выполнением любого кода.Результат этого анализа (байт-код или машинный код) будет связан с этим выражением функции.Это не ждет, когда выполнение достигнет функции, это делается рано (в фоновом режиме в V8 [движок Google в Chrome и Node.js]).
- Как только функция была выполнена, и ничто другое не может ссылатьсяк нему:
- Функция объект и контекст выполнения, связанный с его вызовом, оба имеют право на GC.Когда и как это произойдет, зависит от механизма JavaScript.
- , который оставляет базовый код функции либо байт-кодом (современные версии V8, использующие Ignition, возможно, другие), либо скомпилированным машинным кодом (более старые версииV8 с использованием Full-codegen, другие).Будет ли механизм JavaScript затем отбрасывать этот байт-код или машинный код, будет зависеть от механизма.У меня нет конкретных знаний о механизмах, выбрасывающих байт-код или машинный код для функций, которые никогда не будут доступны снова.Я действительно знаю, что команда V8 тратит много времени на уменьшение воздействия на память, и подбрасывание этого кода кажется мало повисшим плодом.:-) И что они специально потратили время на работу по оптимизации влияния одноразового кода запуска.
Вот пара статей в блоге V8, которые делаютинтересное чтение:
если я напишу это в функции:
function foo()
{
var a=1;
(function(){})();
a++;
}
Существует ли анонимная функция до тех пор, пока foo не вернется, или просто существует во время выполнения этого оператора?
Давайте предположим,опять же, в этой функции есть console.log
, и я прав (это предположениес моей стороны) тот факт, что он опирается на доступную для записи глобальную переменную (console
), означает, что он не может быть просто встроен.
Ответ высокого уровня / спецификации такой же: функция анализируется, когдаСкрипт загружается, создается, когда он достигнут, выполняется и имеет право на сборщик мусора, когда он завершен.Но опять же, это просто концепция высокого уровня.
На уровне двигателя, вероятно, все по-другому:
- Код будет проанализирован , прежде чем любой код вскрипт работает.
- Байт-код или машинный код, вероятно, генерируется до запуска любого кода в скрипте, хотя я, кажется, вспоминаю что-то из блога V8 о разборе, но не сразу компилирует содержимое функций верхнего уровня.Однако я не могу найти эту статью, если бы она была не только у меня в голове.
- Когда выполнение достигает функции, для нее создается функция объект вместе с контекстом выполнения(если механизм не уверен, что он может оптимизировать это, не замечая его в коде).
- После завершения выполнения функция объект и этот контекст выполнения становятся приемлемыми для GC.(Они вполне могли быть в стеке, что делает GC тривиальным, когда
foo
возвращается.) - Основной код, тем не менее, остается в памяти, чтобы использоваться снова (и, если используется достаточно часто, оптимизируется).