JavaScript函数引用调用逻辑及引用类型对象存储位置相关疑问
首先你的前提理解是正确的:函数属于引用类型,变量存储的确实是函数对象的内存引用,而非函数本身的内容。
问题1:函数引用的调用逻辑
你给出的示例代码执行逻辑分两步:
- 执行
let func = function() {..}时:JS引擎会先在堆内存中创建这个匿名函数对象,完成函数的编译、内存分配后,会把这个函数对象的内存首地址赋值给栈上的func变量,也就是你说的「持有引用」。 - 执行
func()时:JS解析器首先读取func变量存储的内存地址,顺着地址找到堆里对应的函数对象,确认是可调用的函数类型后,就会触发函数执行逻辑,将函数推入调用栈执行内部代码。
简单来说,你的理解完全正确:就是直接通过func持有的引用找到对应的函数实体完成调用的。你可以把引用理解成存了门牌号的纸条,调用func()就是拿着纸条上的门牌号找到对应的房子,进去执行里面的操作。
问题2:引用类型的存储位置
所有引用类型(函数、普通对象、数组等)的实体内容,统一存储在**堆内存(Heap)**中,只有指向它的引用(内存地址)会存在栈(Stack)或者其他堆对象的属性里:
- 如果是
let/const/var声明的变量持有的引用,这个地址值会存在调用栈的变量环境中 - 如果是某个对象的属性值为引用类型,这个地址值会存在该对象在堆内存的属性存储空间里
栈的存取速度远快于堆,但空间小、生命周期和执行上下文绑定,所以才会把大小不固定、生命周期可能更长的引用类型实体存在堆里,只在栈上存占用空间固定的地址引用,提高内存管理和运行效率。
内容的提问来源于stack exchange,提问作者happy_story
相关产品推荐
相关产品推荐

