function foo() {
var x = {};
var y = "whatever";
return function bar() {
alert(y);
};
}
var z = foo();
在bar
中引用Y
会调用闭包,只要在垃圾回收器周围保留Z
就不会清理Y
。问题是--x
会发生什么?即使它没有被引用,它也是由那个闭包持有的吗?垃圾回收器是否会看到没有引用x
并将其清理掉?还是只要我坚持z
,X
就会与Y
一起存在?(理想的答案是引用ECMA规范。)
问题是,x会发生什么?
答案因理论和实施而异。
理论上,是的,X
保持活动,因为闭包(匿名函数)引用了调用foo
上下文的绑定对象,其中包括X
。
x = undefined;
让我们看看V8中使用Chrome堆快照特性的代码:
function UsedFlagClass_NoFunction() {}
function UnusedFlagClass_NoFunction() {}
function build_NoFunction() {
var notused = new UnusedFlagClass_NoFunction();
var used = new UsedFlagClass_NoFunction();
return function() { return used; };
}
function UsedFlagClass_FuncDecl() {}
function UnusedFlagClass_FuncDecl() {}
function build_FuncDecl() {
var notused = new UnusedFlagClass_FuncDecl();
var used = new UsedFlagClass_FuncDecl();
function unreachable() { notused; }
return function() { return used; };
}
function UsedFlagClass_FuncExpr() {}
function UnusedFlagClass_FuncExpr() {}
function build_FuncExpr() {
var notused = new UnusedFlagClass_FuncExpr();
var used = new UsedFlagClass_FuncExpr();
var unreachable = function() { notused; };
return function() { return used; };
}
window.noFunction = build_NoFunction();
window.funcDecl = build_FuncDecl();
window.funcExpr = build_FuncExpr();
下面是展开的堆快照:
在处理build_noffunction
函数时,V8成功地识别出无法到达从notused
引用的对象并将其删除,但在其他任何一个场景中都不会这样做,尽管无法到达unreachable
,因此无法通过它到达notused
。
function UsedFlagClass_NoFunction() {}
function UnusedFlagClass_NoFunction() {}
function build_NoFunction() {
new UnusedFlagClass_NoFunction;
var a = new UsedFlagClass_NoFunction;
return function () {
return a
}
}
function UsedFlagClass_FuncDecl() {}
function UnusedFlagClass_FuncDecl() {}
function build_FuncDecl() {
new UnusedFlagClass_FuncDecl;
var a = new UsedFlagClass_FuncDecl;
return function () {
return a
}
}
function UsedFlagClass_FuncExpr() {}
function UnusedFlagClass_FuncExpr() {}
function build_FuncExpr() {
new UnusedFlagClass_FuncExpr;
var a = new UsedFlagClass_FuncExpr;
return function () {
return a
}
}
window.noFunction = build_NoFunction();
window.funcDecl = build_FuncDecl();
window.funcExpr = build_FuncExpr();
正如您所看到的,静态分析告诉CCunreachable
是死代码,因此它完全删除了它。
但是当然,您可能在函数执行过程中使用unreachable
,而在函数完成后就不需要它了。它不是死代码,但它是当函数结束时你不需要的代码。在这种情况下,您必须求助于:
unused = undefined;
在最后。由于您不再需要该函数,您还可以释放它:
unused = unreachable = undefined;
unreachable = undefined;
问题内容: 我试图设置一个变量,该变量位于该闭包内部的闭包外部,但最终不会被设置。然而,我设置变量的值 是 正在打印到控制台。同样,在设置返回变量并自行打印之后,将正确的值打印到控制台。当我返回变量时就会出现问题。其值与初始化时的值相同。这是一些伪代码: 这是不起作用的实际代码: 问题答案: .observeSingleEvent正在异步工作。 您可以执行以下操作: 然后,您可以在任何需要的地方使
问题内容: 我正在努力使用WindowListener关闭JFrame。 我遇到一种情况,客户端登录到服务器,并且当客户端关闭其应用程序时,需要通知服务器。因此,为了通知服务器,应该处理一个类的另一个实例(处理rmi实现)。该实例是我的GUI类中的全局变量。 我在网上搜索了一下,但我能解决的唯一问题是以下结构 这里的问题是我不能使用全局变量。有人可以帮助我解决这个问题吗? 问题答案: 在过去,当我
本文向大家介绍浅谈PHP中关于foreach使用引用变量的坑,包括了浅谈PHP中关于foreach使用引用变量的坑的使用技巧和注意事项,需要的朋友参考一下 写PHP好多年,但仍然会犯低级错误,今天遇到个 foreach中引用变量时的坑,PHP版本为 5.6.12 代码如下: 输出结果 一开始看到第二个 foreach 输出的结果感觉很是莫名其妙,怎么会输出两个 d_d 呢? 仔细想了想,原来因为P
问题内容: Go编译器不应该将循环变量捕获为本地分配的闭包变量吗? 长版: 这也引起了我对C#的困惑,并且我试图理解它。这就是为什么它在C#5.0中已得到修复(原因:循环变量 不能 在循环体内改变)以及未在C#循环中对其进行修复的原因(原因:循环变量 可以 在循环体内改变)。 现在(对我而言),Go中的循环看起来很像C#中的循环,但是尽管事实是我们无法更改这些变量(例如和中)。仍然我们必须首先将它
想象一下我有: 输出: 我想要的是: 现在,正如我所说,这并没有把x设为3,而是把y设为3。我怎样才能改变它,使y充当指向x的指针。我想编辑x,而不是y。之前,我相信我看到了一个关于使用可变变量的页面。我不认为我完全理解Python中变量是如何工作的。
我正在尝试使用HTML、CSS和Javascript制作一个简单的哑巴井字游戏。 在下面的播放器移动函数中,由于JSON对象中存在Typeerror,因此无法调用ComputerMove函数。 下面是JSON对象:- 检查功能始终有效,控制台响应如下 调试时,我发现在此错误之后,计算机移动()函数永远不会被调用。所以请帮忙。