You need to enable JavaScript to run this app. 详解JavaScript函数中return运算符的分步执行流程
优惠活动
大模型
产品
解决方案
定价
更多

详解JavaScript函数中return运算符的分步执行流程

return执行的全流程拆解(对应示例代码逐步骤说明)

代码预解析阶段

JS引擎在正式执行脚本前,会先扫完全量语法结构,给example函数生成语法映射表。这时候代码里写的sum、形参digit1/digit2都只是没有实际内存地址的语法占位符,没有任何实际存储值。

函数调用触发的栈帧创建

全局代码逐行走到const invoke = example(1, 2)这一行时,引擎识别到函数调用请求:

  • 首先在调用栈中压入一块独立的、和全局内存权限完全隔离的新栈帧(也就是常说的函数执行上下文)。这块栈帧的访问边界是内存层面的权限隔离,和代码文本里的大括号没有物理上的绑定关系——全局代码没有任何权限直接读取栈帧内部存的变量。
  • 引擎先把传入的实参1、2绑定到当前栈帧的形参槽位,完成digit1=1、digit2=2的内存写入。

sum变量的赋值过程

执行const sum = digit1 + digit2时,引擎在当前隔离的函数栈帧内部,开辟一块专属存储位置绑定sum标识符,把计算得到的原始值3写入这块位置。
到这一步就能看出来你之前的认知偏差在哪了:你以为sum就存在代码大括号包裹的全局可视范围内,所以觉得“把sum返回出去”是冗余操作。但实际运行时,sum从创建开始就待在和全局完全隔离的独立内存块里,全局代码根本摸不到它的存储位置,不存在“就在原地不需要移动”的前提。

return执行的4个无歧义底层操作

执行return \${sum}``的瞬间,引擎会按固定顺序完成以下动作,没有任何抽象的“返回值”概念套话:

  • 对return后的表达式完成求值:从当前栈帧的sum位置读出存储的3,经过模板字符串拼接得到最终要传递的原始字符串值"3"。
  • 立刻把当前函数栈帧标记为待销毁状态:栈帧内部存的sum、digit1、digit2所有变量马上失去所有访问权限,等待栈弹出、内存回收。
  • 把刚才求值得到的"3",写入到函数调用点预留的返回值槽位——这个槽位是压入函数栈帧之前,就已经在全局栈帧里开好的,全局代码可以直接读取。
  • 中断函数内部所有后续执行流,把当前函数栈帧从调用栈弹出,把执行控制权交回给全局代码的下一行。

全局代码的收尾执行

  • 全局执行上下文从刚才预留的返回值槽位读出"3",把这个值绑定到全局变量invoke上。
  • 此时存储sum的那块函数栈帧内存早已经被弹出销毁,全局代码全程没有直接接触过sum这个标识符,只拿到了return环节传递出来的最终值副本。
  • 最后执行console.log(invoke),把"3"打印到控制台,整个流程结束。

关于return是否冗余的验证

你可以直接把示例代码里的return语句删掉跑一遍:此时函数执行完不会做“把值写入调用点槽位”的动作,槽位会默认填入undefined,最终invoke拿到的值就是undefined,之前在函数内部算出来的sum和拼接的字符串,会跟着栈帧销毁被彻底回收,全局代码完全拿不到。
另外你之前理解的“return把sum送回出发位置”也不成立:sum从始至终都待在被销毁的函数栈帧里,从来没有移动过,它会和栈帧一起被释放;return传递的从来不是变量本身,只是变量对应的值的副本——因为JS里原始类型的拷贝成本极低,这个过程在写代码时完全感知不到。

内容的提问来源于stack exchange,提问作者Codewell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.11.01 03:54:04