据说,javascript在最后引用后从内存中清除变量。
为了这个问题,我只用一个变量为DEMO 创建了一个 JS文件;
//file start
//variable defined
var a=["Hello"]
//refenence to that variable
alert(a[0]);
//
//file end
没有进一步引用该变量,所以我希望javascript清除变量'a'
现在我只是运行了这个页面,然后打开了firebug并运行了这段代码
alert(a[0]);
现在这会警告变量的值,如果语句“Javascript在没有进一步引用后清除变量”,则为什么alert()会显示其值。
是因为全局上下文中定义的所有变量都成为window对象的属性,因为即使在执行文件窗口对象存在之后也是如此。
答案 0 :(得分:4)
当然,在这个例子中要保留变量HAS - 毕竟,你保持环境已被定义在周围。只要你仍然可以访问它就必须保留,所以如果你可以进行这个测试并且它失败了 - 那么JS解释器就是“kaputt”。
请改为:
(function () {
var a = 1;
}());
// and NOW, at THIS point there is nothing any more referencing "a"
当然,从“这里”你不能测试 - 你必须看看JS解释器/编译器的内部存储器结构(今天在V8的时代它更像是“interpiler”或“compreter” “aynway)。
此外,与所有垃圾收集(GC)语言一样,内存不会立即释放,而是取决于Javascript的特定实现所使用的GC策略,这也考虑了当前的内存使用和需求。 GC是一项代价高昂的操作,如果可能的话会延迟和/或在不从实际应用程序中夺走CPU资源时运行。
顺便说一句,略有变化:
(function () {
var a = 1;
//empty function assigned to global namespace,
//in browsers "window" is the global object
window.example_function = function () {};
}());
在此示例中,结果与您的结果相同:只要您查看该页面,“a”的内存永远不会释放:分配给全局对象的属性example_function的函数仍然存在,因此所有环境被定义为必须保留!只有在
之后delete window.example_function
从全局对象中删除该属性 - 最后是指向(空)函数表达式的指针,可以释放变量“a”。另请注意,该功能甚至不使用“a”,请参阅Google并搜索“词法范围”,这是Javascript语言最具定义性的属性之一。
更有趣:
我写过
//define a variable in global namespace
var example_function;
(function () {
var a = 1;
//empty function assigned to global namespace,
//in browsers "window" is the global object
example_function = function () {};
}());
我无法使用“删除”删除它,实际上我无法释放它。这是因为在第一个示例中,example_function成为全局对象(强调)的新属性,而在最后一个示例中,它是一个变量,“delete”仅适用于对象属性。 (我在前面的例子中使用了“windows.example_function”,但没有“window”。它本来就是一样的,example_function会在全局对象中创建为属性。只有“var”语句才会创建变量。)
答案 1 :(得分:2)
是因为全局上下文中定义的所有变量都成为window对象的属性,因为即使在执行文件窗口对象存在之后也是如此。
是。您可能必须关闭窗口,或者从窗口属性中明确删除a
。
答案 2 :(得分:2)
您的脚本的副作用是在全局对象(窗口)中定义了属性名称“a”,因此实际上仍然存在对a的全局引用。
(function()
{
var a = 12;
alert(a);
})();
如果我们将此处的自执行函数的声明包装起来,则在函数退出后将无法访问该函数。
答案 3 :(得分:2)
是的,尽管您可以通过在函数范围内声明并处理变量来缓解此行为:
( function myfunc(a){
var b = 100;
alert(a); // 200
alert(b); // 100
}(200));
alert(a); // undefined
alert(b); // undefined
答案 4 :(得分:0)
引用变量并不意味着以某种方式使用它。只要至少有一个对仍然可以访问的变量的引用,它必须保存在内存中。
查看您的示例,以下行对变量是否被清除没有影响。即使a
没有在任何地方使用,它仍然保持不变。
//refenence to that variable
alert(a[0]);
尽管可以在函数内部创建对象,但其生命周期可能超出函数本身。唯一要记住的是是否仍然存在对相关对象的任何有效引用。考虑这个example,
(function() {
var a = ["Hello"];
var copy = a;
a = null;
setTimeout(function() {
// a: null, copy: ["Hello"]
console.log("a: %o, copy: %o", a, copy);
}, 2000);
})();
变量a
在匿名函数内创建,另一个变量copy
正在引用它。 a
之后设置为null
,但我们仍然可以从copy
获得1个引用。然后我们创建一个超时,它会对同一个变量进行另一次引用。现在即使这个匿名函数在执行setTimeout
后超出范围,我们仍然在超时函数中留下1个引用。因此,当运行超时函数时,此copy
变量仍将保持不变。