JavaScript中eval函数的作用域陷阱与变量可见性解析

作者:闭包旅人

时间:2026-10-29

浏览:255

本文深入解析JavaScript中eval函数的执行机制及其对变量作用域的影响。通过对比局部变量与全局变量在eval中的表现,阐明eval始终在当前调用上下文作用域内执行的原则。当eval被嵌套函数调用时,它能访问外层函数的局部变量,但无法直接访问更外层函数的局部变量,除非这些变量被提升为全局变量。

文章目录

eval函数作用域问题现象

在代码审查过程中,发现了一个关于eval函数的典型问题。尽管查阅了大量技术文章,但对于eval的具体行为仍感到困惑,特别是以下这段代码的表现令人费解:

eval执行机制与变量可见性分析


/*
var start = []
 , end = []
 , timings = [];
*/
function f(){
 //模拟程序执行时间
 var sum = 0;
 for(var i =0 ;i < 100000; i++){
  sum = sum/(i+1);
 }
}
function repeat(n, action){
 for(var i=0; i<n ;i++){
  eval(action); // eval函数
 }
}
function benchmark(){
 var start = []
  , end = []
  , timings = [];
 repeat(100, "start.push(new Date().getTime());f();end.push(new Date().getTime())");
 for (var i =0; i< start.length; i++){
  timings[i] = end[i] - start[i];
 }
 return timings;
}
benchmark(); //结果为:[]
//如果我把上面的benchmark中的局部变量移到全局就一切正常.

局部变量与全局变量的影响

如果将上述benchmark函数中的局部变量提升至全局作用域,代码即可正常运行。

此处eval函数为何会表现出这种差异?这是否意味着eval被赋予了某种别名化的特性?

直接调用eval()时,它始终在调用它的上下文作用域内执行。这意味着它可以访问repeat函数中的局部变量,但无法访问benchmark函数中的局部变量。然而,在函数内部是可以访问到全局作用域变量的。因此,当把start等变量定义为全局变量后,就能得到预期的结果。

直接调用与间接调用的对比


function repeat(n, action){
 for(var i=0; i<n ;i++){
  start.push(new Date().getTime());f();end.push(new Date().getTime()); // eval函数
 }
}

在repeat函数内部,无法直接访问start和end这两个局部变量。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章