eval()
以得出结果。然而,如果可以避免使用
eval()
,我总是回避它,因为它是有害的(而且,正确或错误地说,我一直认为在JavaScript中它甚至更加有害,因为要评估的代码可能会被用户更改)。那么,在什么情况下可以使用它呢?
eval()
以得出结果。eval()
,我总是回避它,因为它是有害的(而且,正确或错误地说,我一直认为在JavaScript中它甚至更加有害,因为要评估的代码可能会被用户更改)。我认为使用eval是合理的情况非常少。你更可能会认为它是合理的,而不是在实际合理的情况下使用它。
安全问题是最为人所知的。但也要注意JavaScript使用JIT编译,这与eval的效果非常不好。Eval有点像编译器中的黑匣子,JavaScript需要能够预测代码(在某种程度上)以便安全、正确地应用性能优化和作用域。在某些情况下,性能影响甚至会影响eval之外的其他代码。
如果您想了解更多信息: https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch2.md#eval
我使用eval
的例子:import。
通常是这样做的。
var components = require('components');
var Button = components.Button;
var ComboBox = components.ComboBox;
var CheckBox = components.CheckBox;
...
// That quickly gets very boring
但是通过使用eval
和一个小的辅助函数,它看起来更好了:
var components = require('components');
eval(importable('components', 'Button', 'ComboBox', 'CheckBox', ...));
importable
的样子可能是这样的(该版本不支持导入具体成员)。
function importable(path) {
var name;
var pkg = eval(path);
var result = '\n';
for (name in pkg) {
result += 'if (name !== undefined) throw "import error: name already exists";\n'.replace(/name/g, name);
}
for (name in pkg) {
result += 'var name = path.name;\n'.replace(/name/g, name).replace('path', path);
}
return result;
}
.replace(/name/g, name).replace('path', path)
。如果 name
包含字符串 "path"
,那么你可能会得到一些意外的结果。 - wberrycomponents
中的每个属性声明一个变量可能是一种代码异味;重构您的代码可能会完全消除这个“问题”。您当前的解决方案只是语法糖。如果您坚持这样做,那么我建议编写自己的预处理器,在部署之前执行。这应该可以避免在生产代码中使用eval
。 - Ruud HeldermanJavaScript的eval()什么时候不是邪恶的?
我总是试图劝阻使用eval。几乎总是有更清晰和可维护的解决方案。即使是JSON解析,也不需要使用Eval。Eval会增加维护难度。不无道理地,像Douglas Crockford这样的大师们都对它表示反感。
但我找到了一个例子,在这个例子中,应该使用它:
例如,我有一个函数,为我构造一个通用的{{link4:google.maps.ImageMapType
}}对象,但我需要告诉它配方,如何从zoom
和coord
参数构造瓦片URL:
my_func({
name: "OSM",
tileURLexpr: '"http://tile.openstreetmap.org/"+b+"/"+a.x+"/"+a.y+".png"',
...
});
function my_func(opts)
{
return new google.maps.ImageMapType({
getTileUrl: function (coord, zoom) {
var b = zoom;
var a = coord;
return eval(opts.tileURLexpr);
},
....
});
}
tileURL: function (zoom, coord) { return 'http://tile.openstreetmap.org/' + b + '/' + a.x + '/' + a.y + '.png'; },
- Casey Chu当你没有宏时,评估在代码生成中非常有用。
例如(愚蠢),如果您正在编写Brainfuck编译器,您可能希望构建一个函数,将指令序列作为字符串执行,并对其进行评估以返回函数。
eval
。 - Ruud Heldermaneval
。 - Ruud Helderman虽然有许多情况下,您可以通过将脚本连接在一起并即时运行来完成所需的任务,但通常您可以使用更强大和可维护的技术。eval 很少是正确的选择:关联数组表示法(obj["prop"]与obj.prop相同),闭包,面向对象技术,函数式技术 - 请使用它们。
仅在测试期间使用,如果可能的话。还要注意,eval() 比其他专门的 JSON 等解析器慢得多。
当您使用解析函数(例如jQuery.parseJSON)解析JSON结构时,它期望JSON文件的完美结构(每个属性名称都在双引号中)。然而,JavaScript更加灵活。因此,您可以使用eval()来避免这种限制。
eval
,特别是从第三方来源获取JSON数据时。请参考JSON.Stringify without quotes on properties?来正确解析“没有引号的JSON键名”的方法。 - Rob Wstring
并将 string
定义为“用双引号括起来的零个或多个Unicode字符序列,使用反斜杠转义”。 - Useless Codeeval
中。在任何严肃的多租户Web应用程序中,有数十个开发人员在同一个代码库上工作,这是不可接受的。 - Ruud Helderman