函数内局部变量返回后,函数的变量对象还在内存中么?

发布于 2022-09-06 12:41:26 字数 760 浏览 25 评论 0

对于闭包、return 还有些疑问:

let v=[];

function temp() {
    let a = [],b=0;
    return a;
}

let t = temp();

最后一行代码执行时,temp 函数内会创建一个作用域链,作用域链中有2个变量对象,全局变量对象G和局部变量对象P,那么上面代码执行完后,我想出三个答案:

理解1:P 没有被销毁,因为 t 保存着对 P 里变量 a 的引用;
理解2:P 已经被销毁了,但 a 没有被销毁,因为 return 返回 a 的引用,然后解除了对 P 的引用;
理解3:P 已经被销毁了,但 a 没有被销毁,因为 return 返回 a 的值,然后解除了对 P 的引用;

我的分析:

理解1的问题在于:这里仅仅是返回一个引用类型的变量,认为是通过变量对象来引用这个变量,从而导致变量对象没有被销毁,如果机制是这样,不是太耗费资源么,直接返回引用然后销毁变量对象就是了;

理解2的问题在于:MDN上看到中英文里解释,return 都是返回的是值,并没有说引用,不过如果返回的是对象,就说是引用的话,那是不是意味着变量对象可能没有被销毁或者在返回后才被销毁了?

我觉得理解3是对的,但不是很确定,请问大家觉得哪个理解是对的?或者上面的理解都不对,有自己的观点?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

禾厶谷欠 2022-09-13 12:41:26

谢邀。

首先说结论。理解1肯定是不对的,因为引用方向是P引用a,而不是a引用P,所以a是否销毁并不会影响到P。

而理解2和3,你的疑惑应该是在到底返回的是a的引用还是a的值上。那么我可以告诉你答案:返回的是a的值,同时也是那个空数组的引用。

a是一个变量,位于栈上,而其实际指向的目标则是那个空数组,后者位于堆上。

a -> []

当函数返回的时候,它所返回的是a的值,也就是该空数组的地址。因此返回后,在内存中的结果是这样的:

a -> []
t----↑

最后,a作为P里面的变量随同P一起被回收,而t则继续保有数组的引用。

守护在此方 2022-09-13 12:41:26

t=[]
返回的是a指向的地址,而不是指向a的地址,所以t和a指向同一个地址,而不是t指向a,a再指向[]。这里没有指针的指针

林空鹿饮溪 2022-09-13 12:41:26
let v=[];

function temp() {
    let a = [],b=0;
    return a;
}

let t = temp();

函数temp执行完毕后,返回了一个对象这个对象就是通过内部变量a初始化生成的数组对象,
这个数组对象被外部变量t引用到,故在数组对象不会被GC(在全局作用域下执行)或将被GC(在一个函数内部执行,在执行执行完毕,且对象没有被返回)。

temp函数在调用栈中执行,其内部局部变量都会在调用完成后被释放,但是期间生成的对象不一定能被GC标识为垃圾。因为有可能生成的对象可能被返回进而被外部引用到。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文