这里有两件事在起作用:激活记录和堆上的对象。
您从全局变量的激活框架开始:
globArray : undefined
并且堆包含出现在您的代码中的文字
ptr0 : "craig"
ptr1 : "silva"
where ptr0
,ptr1
等只是引用内存中特定位置的地址或标签。
当您调用test()
时,解释器会推送一个新的激活框架,其中包含局部变量的框。
globArray : undefined
---------------------
names : undefined
然后解释器评估["craig", "silva"]
哪个在堆上创建了一个对象。
ptr0 : "craig"
ptr1 : "silva"
ptr2 : [ &ptr0, &ptr1 ]
所以ptr2
now 是内存中的一个位置,其中包含一个指向两个值的数组。
这个内存位置现在存储在names
激活记录中的位置,所以你的调用堆栈看起来像
globArray : undefined
---------------------
names : &ptr2
赋值names = ...
不会改变堆,只会改变激活记录。
接下来globArray = names
将一个激活记录条目的内容复制到另一个。
globArray : &ptr2
---------------------
names : &ptr2
然后调用test
结束,激活记录被丢弃,留下
globArray : &ptr2
全局globArray
指向在调用test
. 函数的结尾只是改变了活动的激活记录,而不是堆,所以堆看起来仍然像
ptr0 : "craig"
ptr1 : "silva"
ptr2 : [ &ptr0, &ptr1 ]
所以ptr2
仍然是同一个数组。
所以“名字”不见了,对吧?
names
(激活记录中的条目)消失了,但它指向的对象没有,因为它仍然被globArray
活动激活记录中的条目指向。
后来我打电话给 test2,但它确实显示了元素!所以它必须复制整个对象
不,它只是复制了对该对象占用的堆中位置的引用。由于堆没有更改,因此没有创建新对象,并且堆是创建所有对象的地方。
堆栈和堆是什么以及在哪里?可能会感兴趣。