Javascript 为什么未执行的语句会减慢我的函数?

Javascript 为什么未执行的语句会减慢我的函数?,javascript,performance,Javascript,Performance,我创建了四个不同的函数,如下所示: var normal = function() { return; }; var control = function() { return; alert("Hello, world!"); }; var withArguments = function() { return; arguments; }; var withEval = function() { return; eval(""); };

我创建了四个不同的函数,如下所示:

var normal = function() {
    return;
};
var control = function() {
    return;
    alert("Hello, world!");
};
var withArguments = function() {
    return;
    arguments;
};
var withEval = function() {
    return;
    eval("");
};
因为他们都什么都不做,马上就回来了,我希望他们都有同样的速度。但是,之后,我发现
normal
control
执行得差不多,但是
withArguments
withEval
执行得慢得多


为什么这些未执行的语句会对性能产生影响?由于它们从未执行过,它们怎么可能产生任何效果呢?

简言之,在函数内部调用
eval
,并且能够访问
参数
数组都会在函数调用期间使用额外的设置。如果已知既不执行
参数
也不执行
eval
,则可以跳过此额外设置

编译器不会尝试预测是否实际访问
参数
数组,或者是否实际调用
eval
,它只检查函数中是否存在这些参数

参数
在运行时调用使用
参数
对象的变量函数比调用不使用
参数
对象的“普通”函数的成本更高

声明
参数
对象时绑定执行环境所需的额外步骤如下。创建
参数
对象是一个有点昂贵的15步过程。基本上,
参数
必须用传入的参数填充,并且必须创建
.caller
.callee
属性

该标准规定,除非名为
arguments
的函数中已经声明了参数、变量或函数,否则应在函数进入其执行上下文时创建
arguments
对象

出于优化的目的,大多数浏览器不会实际创建arguments对象,除非函数在某个地方实际使用它(即使在
返回之后)。这就是为什么在引用
参数时会看到性能下降,即使包含它的行从未执行过

eval
输入
eval
code,需要创建一个特殊的执行上下文。基本上,它必须将调用函数的执行上下文的所有属性绑定到
eval
上下文

如果在一个函数中调用了多个
eval
s,那么它们基本上都将执行相同的过程两次。为了优化,如果浏览器检测到函数中存在
eval
(即使在
返回之后),它会预先填充每个
eval
都可以使用的新执行上下文,这样就不需要多次重新创建



请注意,这些优化依赖于浏览器,并且不是标准所要求的,因此某些浏览器可能不会实际执行所描述的优化,或者可能会执行不同的操作。

不同的浏览器/javascript引擎如何处理您的测试脚本?我不确定这会有什么不同,但是你运行过函数返回值的测试吗?+1是最好的答案。FWIW,我在IE10上运行了测试,
withArguments()
测试的运行速度与
normal()
control()
一样快;所以我假设IE10会在这个实例中延迟安装,直到实际需要为止。非常感谢!调用
eval()
的方法也将在全局范围内执行它。