假设我为巨大数组的每个元素创建一个箭头函数
someHugeArray.forEach(record => {
const someValues = [...getAnotherHugeArray()]
const sum = _.sumBy(someValues, 'total')
record.getPrice = () => sum / record.quantity
})
这只是一个示例...因此在创建getPrice
的环境中,我们有一个巨大的数组someValues
,我们可以使用它,但实际上对于getPrice
我们却没有我们获得了所需的值并将其保存到sum
后,不再需要它。
使用代码破坏其价值是否有帮助
someValues = null
或javascript引擎足够聪明,不会在函数的词法环境中保留内存值,而该值未被其使用?
答案 0 :(得分:2)
tl; dr
eval()
时不可能进行优化我发现了一篇很棒的文章系列,对此进行了深入讨论:
这些文章很老但仍然有效,您可以自己进行验证(见下文)。
以您的示例为例:尽管someValues
闭包中未使用{理论上record.getPrice
,但它会被绑定(而不是垃圾回收)。但实际上,仅绑定您在那里使用的变量(sum
)。并且sum
被绑定的事实对someValues
的绑定没有影响,因为sum
是从someValues
派生的,但不需要进一步引用(这是不同的)被定义为const sum = () => _.sumBy(someValues, 'total')
)
验证:在浏览器控制台中执行以下操作:
(() => {
//eval(); // <- uncomment this line for second test
const thisIsUsed = 1;
const isThisBound = 2;
return () => {
debugger;
return ('result: ' + thisIsUsed);
}
})()();
启动调试器后,请查看“ Scope”(Chrome)。您还可以将thisIsUsed
和isThisBound
添加到“监视”列表中。
以下是使用Chrome(Canary,版本85.0.4154.0)的屏幕截图:
使用当前的Firefox(版本76.0.1)可以观察到相同的行为。
根据Dmitry Soshnikov的文章,eval()
可能会破坏优化。这很容易理解,因为引擎随后假定可以访问任何变量。只需在上面的代码示例中取消注释该行,就可以验证此行为。
答案 1 :(得分:0)
由于someValues
是块范围的变量,因此在循环完成后不再存在。
塞巴斯坦评论后的更正
根据MDN,通过显式删除对它的引用(如果对象要在范围内停留更长的时间)来使其不可访问是很有用的。
限制:手动释放内存
有时候方便手动决定何时释放什么内存。为了释放对象的内存,需要使它明确不可访问。
截至2019年,不可能在JavaScript中显式或以编程方式触发垃圾回收。