【发布时间】:2014-06-22 18:29:47
【问题描述】:
所以我尝试创建自己的 JS 框架只是为了我自己的乐趣(然后可能会转化为有用性),我大部分时间都专注于动态生成 JS(因为 JS 作为语言的水平更高) the-middle 是个坏主意,IMO)
我遇到了一个麻烦。我试图做以下事情
var f = null;
var converted = "f = function(){ <do something here>";
for(var x in list)
converted+=list[x];
converted+="};";
eval(converted);
所以这几乎将构造函数写入 f,我可以稍后执行。
但这里有个问题——它运行得比我完全在文件中编写 f 的代码要慢,这很奇怪。让我解释一下为什么这对我来说很奇怪:当您每次只运行 eval 时,Chrome 预编译器(或任何浏览器预编译器 - chrome 是我的目标)无法缓存编译代码,因为它期望它会随着每个跑。
但是,当您将其保存到函数时,它会创建一个新的 VM 机器文件,因为保存函数的代码后,您无法更改它。那么,为什么当我进行这样的评估时,它的运行速度比正常执行慢?我的意思是在代码多次执行之后。为什么这很重要?
PS:我上面展示的方法每次都比评估更快。所以我不明白为什么秒表会在中间显示时间,再次忽略前 1-10 个调用
PPS:测试用例:http://jsperf.com/evaluated-function-vs-real-function/2
【问题讨论】:
-
when you save this to a function- 你如何将它保存到函数中?从您发布的代码中,我没有看到评估代码被转换为函数。 -
相信我,确实如此。当您评估变量“已转换”时,执行 f=function()...,它将新函数写入变量 f
-
当我测试它时,我发现常规函数和使用
eval创建的函数之间没有性能差异:jsperf.com/evaluated-function-vs-real-function -
啊,没关系 - 我没有看到
f在您评估的代码之外的任何地方引用。 -
这里使用 Function 构造函数可能会有所帮助。说真的,以这种方式使用 eval 是非常危险的,并且被认为是有害的。至少您应该将函数值分配为 eval 调用的结果,即
var converted = "var f = function() { ...";...converted += "}; f;"var f = eval(converted);但我建议var f = new Function(converted);其中converted只是您的函数的主体。
标签: javascript google-chrome eval