简单的答案:如果str
没有从其他任何地方引用 的值(并且str
没有从 引用restofprogram
它本身),它将在function (str) { ... }
返回后立即变得无法访问。
详细信息:V8 编译器将真正的局部变量与由闭包捕获的、由with语句或调用隐藏的所谓上下文变量区分开来。 eval
局部变量存在于堆栈中,并在函数执行完成后立即消失。
上下文变量存在于堆分配的上下文结构中。当上下文结构消失时,它们就会消失。这里要注意的重要一点是,来自同一作用域的上下文变量存在于同一结构中。让我用一个示例代码来说明它:
function outer () {
var x; // real local variable
var y; // context variable, referenced by inner1
var z; // context variable, referenced by inner2
function inner1 () {
// references context
use(y);
}
function inner2 () {
// references context
use(z);
}
function inner3 () { /* I am empty but I still capture context implicitly */ }
return [inner1, inner2, inner3];
}
在这个例子中变量x
将尽快消失outer
的回报,但变量y
,并z
只有当将消失两个 inner1
,inner2
和 inner3
死。发生这种情况是因为y
和z
分配在相同的上下文结构中,并且所有三个闭包都隐式地引用了这个上下文结构(即使inner3
没有显式使用它)。
当您开始使用with -statement、try/catch -statement 时,情况会变得更加复杂,它们在 V8 上在 catch 子句或 global 中包含一个隐含的with -statement eval
。
function complication () {
var x; // context variable
function inner () { /* I am empty but I still capture context implicitly */ }
try { } catch (e) { /* contains implicit with-statement */ }
return inner;
}
在这个例子中x
只会在inner
死亡时消失。因为:
- try / catch语句-包含隐与在catch子句语句来
- V8 假设 any with -statement 会影响所有本地人
这会强制x
成为上下文变量并inner
捕获上下文,x
直到inner
死亡为止。
一般来说,如果您想确保给定的变量不会保留某个对象的时间超过实际需要的时间,您可以通过分配给该变量来轻松破坏此链接null
。