该eval()
函数计算以字符串形式表示的JavaScript代码。
句法
eval(string)
参数
string
- 代表一个JavaScript表达式,语句或语句序列的字符串。表达式可以包括变量和现有对象的特性。
返回值
评估代表给定的代码完成值的字符串。如果完成值为空,{{jsxref(“未定义”)}}被返回。
描述
eval()
是全局对象的功能属性。
该的参数eval()
函数是一个字符串。如果字符串表示表达式,eval()
计算表达式。如果该参数代表一个或多个JavaScript语句,eval()
评估声明。不要打电话eval()
来评估一个算术表达式; JavaScript的自动计算算术表达式。
如果你构建一个算术表达式作为一个字符串,就可以使用eval()
在以后的时间来评估它。例如,假设你有一个变量x
。您可以推迟涉及表达式的评价x
通过分配表达式的字符串值,说“ 3 * x + 2
”,给一个变量,然后调用eval()
在脚本稍后。
如果参数eval()
不是字符串,eval()
返回参数不变。在下面的例子中,String
构造被指定,并eval()
返回一个String
对象,而不是评估串。
的eval(新的String(“2 + 2”)); //返回包含“2 + 2”的String对象 的eval(“2 + 2”); //返回4
您可以通过使用解决此限制在一个通用的方式toString()
。
VAR表达式=新的String(“2 + 2”); 的eval(expression.toString());
如果您使用的eval
函数间接地经由以外的引用调用它eval
, 为的ECMAScript 5的它工作在全局范围内,而不是本地范围; 这意味着,例如,该函数声明创建全局函数,并且该码被评估没有访问到它被称为的范围内的局部变量。
功能测试(){ 变种X = 2,Y = 4; 的console.log(的eval(“X + Y”)); //直接调用,使用本地范围,结果是6 VAR geval = EVAL; 的console.log(geval(“X + Y”)); //间接调用,采用全球范围内,引发ReferenceError因为`x`未定义 }
不要使用eval
不必要的!
eval()
是一种危险的功能,它执行它与呼叫者的权限传递的代码。如果运行eval()
与可能是由恶意方受到影响的字符串,你可能最终运行用户计算机上的恶意代码网页/展期的权限。更重要的是,第三方代码可以看到其中的范围eval()
被调用,这可以导致在办法其中类似{{jsxref(“Global_Objects /功能”,“功能”)}}不易可能的攻击。
eval()
一般也比其它慢,因为它必须调用JS解释,而许多其他构建体是由现代JS引擎优化。
有更安全(更快!)替代eval()
常见的用例。
访问成员属性
你不应该使用eval()
对属性名称转换为属性。考虑下面的例子,其中要访问的对象的属性,直到执行代码是未知的。这可以用的eval来完成:
VAR OBJ = {A:20,B:30}; VAR PROPNAME = getPropName(); //返回“a”或“b”的 的eval(“VAR结果=目标文件”+ PROPNAME);
然而,eval()
没有必要在这里。事实上,这里不鼓励使用。相反,使用属性访问,这是更快,更安全:
VAR OBJ = {A:20,B:30}; VAR PROPNAME = getPropName(); //返回“a”或“b”的 VAR的结果= OBJ [PROPNAME] //物镜[“一个”]是相同的obj.a
使用函数而不是评估的代码片段
JavaScript有一流的功能,这意味着你可以函数作为参数传递给其他的API,将它们存储在变量和对象的属性,等等。很多的DOM API在设计时考虑到这一点,所以你可以(也应该)写:
//代替的setTimeout(“...”,1000)使用方法: 的setTimeout(函数(){...},1000); //而不是elt.setAttribute(“onclick”事件,“...”)使用: elt.addEventListener(“点击”,函数(){...},FALSE);
闭包也作为一种方式来创建参数化功能,而无需连接字符串很有帮助。
JSON解析(字符串转换为JavaScript对象)
如果你调用该字符串eval()
的包含数据(例如,一个数组:"[1, 2, 3]"
),而不是代码,你应该考虑切换到JSON,这使得该字符串使用JavaScript语法的子集来表示数据。又见下载JSON和JavaScript扩展。
请注意,由于JSON语法是比较JavaScript语法的限制,许多有效的JavaScript文字不会解析为JSON。例如,尾随逗号没有在JSON允许的,并在对象文本属性名称(键)必须用引号括起来。一定要使用一个JSON序列生成稍后将解析为JSON字符串。
通过数据,而不是代码
例如,设计凑的网页的网页内容的扩展可能在定义的规则,刮的XPath,而不是JavaScript代码。
在有限的权限运行代码
如果你必须运行代码,可以考虑降低权限运行它。这个建议主要适用于扩展和XUL应用程序,它可以使用Components.utils.evalInSandbox这一点。
例子
运用 eval
在下面的代码,既包含语句eval()
返回42.第一个计算字符串“ x + y + 1
”; 第二个计算字符串“ 42
”。
变种X = 2; 变种Y = 39; VAR Z =“42”; 的eval(“X + Y + 1”); //返回42 的eval(Z); //返回42
使用eval
评估JavaScript语句的字符串
下面的示例使用eval()
来评估串str
。该字符串由打开一个警告对话框,指定JavaScript语句z
如果值为42 x
是五,并分配0 z
,否则。当执行第二条语句,eval()
将导致执行这些语句中,并且它也将评估一组语句,并返回分配给的值z
。
VAR X = 5; 无功海峡=“如果(X == 5){执行console.log('z是42'); Z = 42;}否则Z = 0;”; 的console.log(“z是”的eval(STR));
最后表达式求值
eval()
返回最后计算的表达式的值。
无功海峡=“如果(一){1 + 1;}其他{1 + 2;}”; VAR一个= TRUE; 变种B =的eval(STR); //返回2 的console.log(“b为:”+ B); A = FALSE; B =的eval(STR); //返回3 的console.log(“b为:”+ B);
eval
作为定义函数字符串要求“(”和“)”作为前缀与后缀
变种fctStr1 =“函数a(){}” 变种fctStr2 =“(函数a(){})” VAR fct1 =的eval(fctStr1)//返回未定义 VAR fct2 =的eval(fctStr2)//返回一个函数
产品规格
规范 | 状态 | 评论 |
---|---|---|
{{SpecName('ES1')}} | {{Spec2('ES1')}} | 初始定义。 |
{{SpecName('ES5.1','#仲丁基15.1.2.1','的eval')}} | {{Spec2('ES5.1')}} | |
{{SpecName('ES6','#仲的eval-X','的eval')}} | {{Spec2('ES6')}} | |
{{SpecName('ESDraft','#仲的eval-X','的eval')}} | {{Spec2('ESDraft')}} |
浏览器兼容性
{{CompatibilityTable}}
特征 | 铬 | 火狐(壁虎) | IE浏览器 | 歌剧 | 苹果浏览器 |
---|---|---|---|---|---|
基本支持 | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} |
特征 | Android版 | Android版Chrome | Firefox移动(壁虎) | IE浏览器移动 | Opera移动 | 移动Safari浏览器 |
---|---|---|---|---|---|---|
基本支持 | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} | {{CompatVersionUnknown}} |
Gecko的具体注意事项
- 历史上
eval()
有一个任选的第二个参数,指定一个对象在其上下文中评价为要执行。这种说法是不规范的,并且从SpiderMonkey的壁虎在1.9.1(火狐3.5)被删除。见{{错误(442333)}}。
也可以看看
- {{jsxref(“Global_Objects / uneval”,“uneval()”)}}
- 属性访问器