Это, в основном, вопрос из-за любопытства. Рассмотрим следующие функции
var closure ;
function f0() {
var x = new BigObject() ;
var y = 0 ;
closure = function(){ return 7; } ;
}
function f1() {
var x = BigObject() ;
closure = (function(y) { return function(){return y++;} ; })(0) ;
}
function f2() {
var x = BigObject() ;
var y = 0 ;
closure = function(){ return y++ ; } ;
}
В каждом случае, после того, как функция была выполнена, есть (я думаю), чтобы не дойти до x, и поэтому BigObject может быть собрано в мусор, если x является последней ссылкой на него. Простой мыслящий интерпретатор будет захватывать всю цепочку цепей всякий раз, когда оценивается выражение функции. (Во-первых, вам нужно сделать это, чтобы делать звонки на работу eval - пример ниже). Более разумная реализация может избежать этого в f0 и f1. Еще более разумная реализация позволила бы удержать y, но не x, как это необходимо для эффективного f2.
Мой вопрос в том, как справляются с этими ситуациями современные механизмы JavaScript (JaegerMonkey, V8 и т.д.)?
Наконец, вот пример, который показывает, что переменные, возможно, необходимо сохранить, даже если они никогда не упоминаются во вложенной функции.
var f = (function(x, y){ return function(str) { return eval(str) ; } } )(4, 5) ;
f("1+2") ; // 3
f("x+y") ; // 9
f("x=6") ;
f("x+y") ; // 11
Тем не менее, существуют ограничения, которые препятствуют проникновению в вызов eval способами, которые могут быть упущены компилятором.