-1

我认为这是一个有点奇怪的问题。但我会解释我的意思。

事实证明,Mark-and-sweep算法在从这个函数中出去后清除了这个例子中的对象引用。

function f() {
    let a = 'some text';
    var obj1 = {};
    var obj2 = {};
    obj1.p = obj2; // obj1 references obj2
    obj2.p = obj1; // obj2 references obj1. This creates a cycle.
}
f();

那么,如果 Mark-and-sweep 只能清除对象,那么这个函数中的所有变量都会保留吗?我的意思是我们不能在函数之外使用它们。这种行为仅仅是因为“JS规则”吗?

PS我的意思是,在知道这些信息之前,我认为我们不能使用函数中的所有变量,因为在我们退出这个函数后它们会被删除。

4

1 回答 1

1

原来Mark-and-sweep算法从这个函数出去后清除了这个例子中的对象引用

可以是标记和扫描。它可能是引用计数。它们可以在堆栈上(是的,对象可以在堆栈上)。它可以是其他几种垃圾收集策略中的任何一种。归根结底,用 JavaScript 术语来说最重要的是,一旦函数返回,这些对象都不再可访问,因此 JavaScript 引擎可以使用任何启发式或算法从内存中删除这些对象。(它也不能这样做,垃圾收集不是强制性的,但它在特定环境之外的现实世界中是通用的,例如一些嵌入式环境。)

那么......这个函数中的所有变量都保留吗?我的意思是我们不能在函数之外使用它们。这种行为仅仅是因为“JS规则”吗?

最有可能的是,它们都不会留下来,因为它们中的任何一个都没有使用。

PS我的意思是,在知道这些信息之前,我认为我们不能使用函数中的所有变量,因为在我们退出这个函数后它们会被删除。

这取决于函数返回后是否在函数中创建了任何闭包。f在您的示例中,没有,因此可以从内存中删除调用的整个上下文。但这不是真的:

function counter(value) {
    return function() {
        return value++;
    };
}

const f = counter(0);
console.log(f()); // 0
console.log(f()); // 1
console.log(f()); // 2

在那里,返回的函数关闭了调用的环境counter,因此value参数(本质上与局部变量相同)没有被清理,它被保留是因为环境被保留,因为函数具有对它的引用. 在该代码中,只要f常量具有对函数的引用,value就会保留环境和其中的内容。

更多的:

于 2021-04-14T17:47:36.320 回答