- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我敢肯定以前有人问过类似的问题,但是没有回答我的问题的类似问题的数量迫使我问自己。
假设您有以下代码:
(function() {
"use strict";
var somearray=[1, 2, 3];
for(var i=0; i<somearray.length; i++) {
//do something
}
function loop() {
//do something repeatedly
requestAnimationFrame(loop);
}
loop();
})();
既然变量i
被定义在与永久循环相同的范围内,那么它是否即使未被使用也继续存在,等待最终可能被使用的可能性?或者 JavaScript 的(尤其是 Chrome 的 V8)垃圾收集器是否足够智能来确定它是否会被使用?
我知道我可以将 console.log(i)
添加到某个地方的循环中,然后 i
将继续存在,只要它被引用,但它会继续吗在继续存在的范围内不被引用地存在?
最佳答案
这实际上不是关于垃圾收集器的问题,而是闭包是否优化的问题。执行环境的闭包优化器可能会确定变量未被嵌套函数引用(关闭),然后将它们从闭包环境中删除。如果是这样,那么它们就是收集的候选对象。如果闭包优化器没有运行,或者它确定 i
和 somearray
被引用,或者它不能确定 i
和 的生命周期>somearray
,那么它们将不会被收集,因为它们是闭包环境所需要的。
一个函数有一个隐式环境,它包括封闭函数(以及封闭它的所有函数)中的所有局部变量。该环境将捕获这些变量引用的任何对象。闭包优化器静态分析函数以确定是否可以 trim 环境以消除未引用的变量。如果变量从环境中消失,一旦函数调用结束,它们就成为收集的候选对象。
所有现代 JavaScript 引擎都有闭包优化器。
一些可能禁用或限制闭包优化器的常见事情包括处于 Debug模式、使用直接 eval()
、使用 arguments
数组、使用 deprecated caller
等功能。
如您所见,这显然取决于 \\do something repeatly
做了什么以及代码在什么上下文中执行。
无论 \\do something repeatly
做什么,确保它们不被捕获的一种方法是确保它们不再在范围内。一个立即执行的函数就可以做到这一点,因此将您的代码更改为,
(function() {
"use strict";
(function() {
var somearray=[1, 2, 3];
for(var i=0; i<somearray.length; i++) {
//do something
}
})();
function loop() {
//do something repeatedly
requestAnimationFrame(loop);
}
loop();
})();
将确保数组不会留在内存中。
关于javascript - 这个垃圾收起来了吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21126718/
我是一名优秀的程序员,十分优秀!