eval不创建独立执行上下文,而是复用当前上下文,共享作用域链、this和arguments,无栈帧新增,变量声明提升至外层作用域,无法形成闭包。

eval 执行上下文不是独立创建的函数上下文,它不生成新的作用域,而是直接复用当前所处的执行上下文——也就是说,它“嵌入”在调用它的那个函数(或全局)环境中运行。
eval 没有自己专属的执行上下文栈帧
普通函数每次调用都会压入一个新的函数执行上下文到执行栈,包含独立的变量对象(VO)、作用域链、this 绑定和 arguments。而 eval 不会触发栈帧新增;它只是在当前上下文中解析并执行字符串代码,相当于把那段代码“抄进”当前函数体里再运行。
- 函数调用:f() → 创建新函数上下文 → 执行 → 返回后销毁
- eval("x = 1") 在 f 内部执行 → x 直接写入 f 的变量对象,不新建上下文
作用域链完全共享,无隔离性
eval 可以自由读写当前函数的局部变量、形参、内部声明的函数,甚至能用 var 声明新变量并挂载到当前上下文的变量对象上。
- function f(a) { const b = 2; eval("console.log(a, b); var c = 3"); console.log(c); } —— 全部可访问、可定义
- new Function("a", "return a + 1") 则无法访问 a 或 b,除非显式传参
没有独立的 this 和 arguments 绑定
eval 中的 this 就是外层函数的 this,arguments 也直接指向外层函数的 arguments 对象。它不创建新的 this 绑定逻辑,也不生成自己的 arguments。
- 在严格模式下,eval 内部的 this 仍继承外层,不会变成 undefined
- 普通函数执行上下文则会在创建阶段就明确绑定 this 和初始化 arguments
生命周期依附于外层,不可单独管理
eval 执行完毕后,不会留下任何上下文痕迹;它没有“退出”概念,也不参与执行栈弹出流程。而函数上下文在 return 或异常后会被引擎明确销毁,变量对象随之释放(若无闭包引用)。
- eval 的变量提升行为与外层一致:var 声明会被提升到外层函数作用域顶部
- 它不能形成闭包,因为它本身不构成一个函数环境


















