函数内局部变量返回后,函数的变量对象还在内存中么?
对于闭包、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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
谢邀。
首先说结论。理解1肯定是不对的,因为引用方向是P引用a,而不是a引用P,所以a是否销毁并不会影响到P。
而理解2和3,你的疑惑应该是在到底返回的是a的引用还是a的值上。那么我可以告诉你答案:返回的是a的值,同时也是那个空数组的引用。
a是一个变量,位于栈上,而其实际指向的目标则是那个空数组,后者位于堆上。
a -> []
当函数返回的时候,它所返回的是a的值,也就是该空数组的地址。因此返回后,在内存中的结果是这样的:
a -> []
t----↑
最后,a作为P里面的变量随同P一起被回收,而t则继续保有数组的引用。
t=[]
返回的是a指向的地址,而不是指向a的地址,所以t和a指向同一个地址,而不是t指向a,a再指向[]。这里没有指针的指针
函数temp执行完毕后,返回了一个对象这个对象就是通过内部变量a初始化生成的数组对象,
这个数组对象被外部变量t引用到,故在数组对象不会被GC(在全局作用域下执行)或将被GC(在一个函数内部执行,在执行执行完毕,且对象没有被返回)。
temp函数在调用栈中执行,其内部局部变量都会在调用完成后被释放,但是期间生成的对象不一定能被GC标识为垃圾。因为有可能生成的对象可能被返回进而被外部引用到。