对于闭包、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是对的,但不是很确定,请问大家觉得哪个理解是对的?或者上面的理解都不对,有自己的观点?
谢邀。
首先说结论。理解1肯定是不对的,因为引用方向是P引用a,而不是a引用P,所以a是否销毁并不会影响到P。
而理解2和3,你的疑惑应该是在到底返回的是a的引用还是a的值上。那么我可以告诉你答案:返回的是a的值,同时也是那个空数组的引用。
a是一个变量,位于栈上,而其实际指向的目标则是那个空数组,后者位于堆上。
a -> []
当函数返回的时候,它所返回的是a的值,也就是该空数组的地址。因此返回后,在内存中的结果是这样的:
a -> []
t----↑
最后,a作为P里面的变量随同P一起被回收,而t则继续保有数组的引用。