垃圾回收在 JavaScript 中是如何工作的?

2023-05-13前端开发问题
2

本文介绍了垃圾回收在 JavaScript 中是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

限时送ChatGPT账号..

垃圾回收在 JavaScript 中是如何工作的?它类似于 .NET 垃圾收集吗?是不是因为 VBScript 中垃圾回收的实现很糟糕,人们才避免使用它,而偏爱 JavaScript 作为他们的标准客户端语言?

解决方案

垃圾回收是如何工作的?

简短的回答是:当一块内存(比如一个对象)不再可访问时,它就有资格被回收.何时、如何或是否回收完全取决于实现,不同的实现方式不同.但在语言层面,它是自动的.

例如:

函数 foo() {变量栏;酒吧 = 新的真正大规模对象();bar.someCall();}

foo 返回时,bar 指向的对象自动可用于垃圾回收,因为没有任何东西可以引用它.

对比:

函数 foo() {变量栏;酒吧 = 新的真正大规模对象();bar.someCall();返回栏;}//其他地方var b = foo();

...现在对该对象的引用在调用中仍然存在,并且一直存在,直到/除非调用者将其他内容分配给 bb 超出范围.

同时对比:

函数 foo() {变量栏;酒吧 = 新的真正大规模对象();bar.someCall();设置超时(函数(){alert("三秒过去了");}, 3000);}

这里,即使在foo返回后,定时器机制也有对定时器回调的引用,而定时器回调 —闭包 —对创建它的上下文有一个引用,该上下文又包含 bar 变量.因此,理论上,当 foo 返回时,bar 所指的内容不能立即用于垃圾回收.相反,它会一直保留到计时器触发并释放其对回调的引用,从而使回调及其引用的上下文符合 GC 条件.(在实践中,现代 JavaScript 引擎可以并且确实优化了闭包.例如,在上面,静态分析显示回调不引用 bar,并且不包含任何 evalnew Function 代码可能会在运行时动态引用它,因此 JavaScript 引擎可以安全地将 bar 排除在函数引用的上下文之外,从而使它所指的东西有资格获得 GC — 和现代的).(在这篇文章中了解更多关于闭包的信息.)p>

JavaScript 在清理循环引用时没有问题,顺便说一句,例如:

函数 foo() {变量 a, b;一个 = {};b = {};b.refa = a;a.refb = b;}

foo 返回时,a 指的是 b 并且反之亦然的事实不是问题.由于没有其他内容涉及它们中的任何一个,因此它们都可以被清理.在 IE 上,如果其中一个对象是主机提供的对象(例如 DOM 元素或通过 new ActiveXObject 创建的东西)而不是 JavaScript 对象,则这为真.(例如,如果您将 JavaScript 对象引用放在 DOM 元素上,并且 JavaScript 对象引用回 DOM 元素,即使没有人引用它们中的任何一个,它们也会在内存中相互保存.)但这是一个 IE bug问题,不是 JavaScript 的问题.

回复:

<块引用>

是因为 vbscript GC 不好,人们将 javascript 作为他们的标准客户端 api 吗?

JavaScript 是原始客户端网络脚本语言.VBScript 只是在后来微软推出浏览器时才出现,并且只在微软浏览器中得到支持.如果您想使用最广泛的浏览器,JavaScript 曾经是并且现在是唯一的客户端脚本游戏.<subjective>它也是经典 VBScript 语言的八倍.;-) </主观的>

How does garbage collection work in JavaScript? Is it similar to .NET garbage collection? And is it because the implementation of garbage collection in VBScript is bad that people avoided it and established a preference for JavaScript as their standard client-side language?

解决方案

How does garbage collection work?

The short answer is: When a block of memory (an object, say) is no longer reachable, it is eligible to be reclaimed. When, how, or whether it is reclaimed is entirely up to the implementation, and different implementations do it differently. But at a language level, it's automatic.

For example:

function foo() {
    var bar;

    bar = new ReallyMassiveObject();
    bar.someCall();
}

When foo returns, the object bar points to is automatically available for garbage collection because there is nothing left that has a reference to it.

Contrast with:

function foo() {
    var bar;

    bar = new ReallyMassiveObject();
    bar.someCall();
    return bar;
}
// elsewhere
var b = foo();

...now a reference to the object survives the call, and persists until/unless the caller assigns something else to b or b goes out of scope.

Also contrast with:

function foo() {
    var bar;

    bar = new ReallyMassiveObject();
    bar.someCall();
    setTimeout(function() {
        alert("Three seconds have passed");
    }, 3000);
}

Here, even after foo returns, the timer mechanism has a reference to the timer callback, and the timer callback — a closure — has a reference to the context where it was created, which in turn contains the bar variable. As a result, in theory, what bar refers to isn't available for garbage collection immediately when foo returns. Instead, it's kept around until the timer fires and releases its reference to the callback, making the callback and the context it refers to eligible for GC. (In practice, modern JavaScript engines can and do optimize closures where they can. For instance, in the above, static analysis shows the callback doesn't refer to bar, and doesn't contain any eval or new Function code that might refer to it dynamically at runtime, so the JavaScript engine can safely leave bar out of the context the function refers to, thus making what it refers to eligible for GC — and modern ones do). (More about closures in this article.)

JavaScript has no problem handling cleaning up circular references, btw, so for instance:

function foo() {
    var a, b;

    a = {};
    b = {};
    b.refa = a;
    a.refb = b;
}

When foo returns, the fact that a is referring to b and vice-versa isn't a problem. Since nothing else refers to either of them, they can both get cleaned up. On IE, this is not true if one of the objects is a host-provided object (such as a DOM element or something created via new ActiveXObject) instead of a JavaScript object. (So for instance, if you put a JavaScript object reference on a DOM element and the JavaScript object refers back to the DOM element, they keep each other in memory even when no one is referencing either of them.) But that's an IE bugissue, not a JavaScript thing.

Re:

is it because the vbscript GC is bad that people reverted to javascript as their standard client side api?

JavaScript was the original client-side web scripting language. VBScript only came later, when Microsoft came out with a browser, and was only ever supported in Microsoft browsers. JavaScript was and is the only client-side scripting game in town if you want to work with the broadest range of browsers. <subjective>It's also about eight times the language classic VBScript ever was. ;-) </subjective>

这篇关于垃圾回收在 JavaScript 中是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

The End

相关推荐

js删除数组中指定元素的5种方法
在JavaScript中,我们有多种方法可以删除数组中的指定元素。以下给出了5种常见的方法并提供了相应的代码示例: 1.使用splice()方法: let array = [0, 1, 2, 3, 4, 5];let index = array.indexOf(2);if (index -1) { array.splice(index, 1);}// array = [0,...
2024-11-22 前端开发问题
182

JavaScript小数运算出现多位的解决办法
在开发JS过程中,会经常遇到两个小数相运算的情况,但是运算结果却与预期不同,调试一下发现计算结果竟然有那么长一串尾巴。如下图所示: 产生原因: JavaScript对小数运算会先转成二进制,运算完毕再转回十进制,过程中会有丢失,不过不是所有的小数间运算会...
2024-10-18 前端开发问题
301

JavaScript(js)文件字符串中丢失"\"斜线的解决方法
问题描述: 在javascript中引用js代码,然后导致反斜杠丢失,发现字符串中的所有\信息丢失。比如在js中引用input type=text onkeyup=value=value.replace(/[^\d]/g,) ,结果导致正则表达式中的\丢失。 问题原因: 该字符串含有\,javascript对字符串进行了转...
2024-10-17 前端开发问题
437

layui中table列表 增加属性 edit="date",不生效怎么办?
如果你想在 layui 的 table 列表中增加 edit=date 属性但不生效,可能是以下问题导致的: 1. 缺少日期组件的初始化 如果想在表格中使用日期组件,需要在页面中引入 layui 的日期组件,并初始化: script type="text/javascript" src="/layui/layui.js"/scrip...
2024-06-11 前端开发问题
455

Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript
Rails/Javascript: How to inject rails variables into (very) simple javascript(Rails/Javascript:如何将 rails 变量注入(非常)简单的 javascript)...
2024-04-20 前端开发问题
5

CoffeeScript 总是以匿名函数返回
CoffeeScript always returns in anonymous function(CoffeeScript 总是以匿名函数返回)...
2024-04-20 前端开发问题
13