Please note, this is a STATIC archive of website developer.mozilla.org from 03 Nov 2016, cach3.com does not collect or store any user information, there is no "phishing" involved.

摘要

将一个JavaScript代码字符串求值成特定的对象。

语法

eval(string)

参数

string
一个字符串表示了一个JavaScript表达式,声明, 或声明的序列。表达式可以包括变量和已存在对象的属性。
object
An optional argument; if specified, the evaluation is restricted to the context of the specified object.

描述

eval()是一个顶级函数并且跟任何对象无关。

eval()的参数是一个字符串。如果字符串表示了一个表达式,eval()会对表达式求值。如果参数表示了一个或多个JavaScript声明, 那么eval()会执行声明。不要调用eval()来为算数表达式求值; JavaScript 会自动为算数表达式求值。

如果要将算数表达式构造成为一个字符串,你可以用eval()在随后对其求值。比如,你有一个变量 x ,你可以通过一个字符串表达式来对涉及x的表达式延迟求值,将 "3 * x + 2",当作变量,通过在脚本中调用eval(),随后求值。

如果参数不是字符串,eval()将会将参数原封不动的返回。在下面的例子中,字符串构造器是指定的,eval()返回了字符串对象而不是对字符串求值。

eval(new String("2 + 2")); // 返回了包含"2 + 2"的字符串对象
eval("2 + 2");             // returns 4

你可以使用变通的方法来应对这个限制,如使用toString()

var expression = new String("2 + 2");
eval(expression.toString());

你可以间接的使用 eval(), 如使用变量来引用 eval(),然后调用它。 如果你这么做了,那么这个时候目标字符串中的 javascript 代码将被直接视为在全局作用域下执行, 这是因为 ES 规范里明确规定了对 eval 的 直接调用和间接调用会被区别对待。因此, 下面的例子中便出现了 x 未定义 的状况:

function test() {
  var x = 2, y = 4;
  console.log(eval("x + y"));  // Direct call, uses local scope, result is 6
  var geval = eval;
  console.log(geval("x + y")); // Indirect call, uses global scope, throws ReferenceError because `x` is undefined
}

避免在不必要的情况下使用eval

eval() 是一个危险的函数, 它可以像拥有调用者的权力一样调用代码。如果你使用了字符串来运行eval(),那么你的代码可能被恶意方(不怀好意的人)影响, 通过在使用方的机器上使用恶意代码,可能让你失去在网页或者扩展程序上的权限。

常规用例的安全会被eval()改变。

解析 JSON

在扩展中下载JSON和JavaScript

转化成员属性

你不应该在属性里通过eval来转化属性。考虑下面的例子: getFieldName(n) 函数将指定的表单元素按字符串返回, 将表单的第三个元素赋值给了一个变量声明 field ,第二句声明使用eval()来展示表单元素的值。

var field = getFieldName(3);
document.write("The field named ", field, " has value of ",
   eval(field + ".value"));

也许,这里的eval()不是必要的,事实上,这里使用eval()是不鼓励的。 取而代之的是使用 member operators, 那会快很多:

var field = getFieldName(3);
document.write("The field named ", field, " has value of ",
   field[value]);

Cross-implementation compatibility

应该被注意的是,eval的第二个参数是非标准的,在JavaScript实现中不被支持的;在写这篇文章的时候,Rhino没有提供支持,也不是 Safari's 的核心JavaScript代码。

为了维持兼容性,采用交叉实现,它被推荐第二个参数不被使用,为了达到相同的效果,不如使用 with 声明 。

eval(string,object);

使用

with (object) {
  eval(string);
}

例子

下面的例子展示了使用 document.write来输出。在服务器端的 JavaScript,你可以使用write 函数来达到document.write的效果。

举例: 使用 eval

在下面的代码中,两种声明都返回了42。第一种是对字符串 "x + y + 1"求值;第二种是对字符串 "42"求值。

var x = 2;
var y = 39;
var z = "42";
eval("x + y + 1"); // returns 42
eval(z);           // returns 42 

举例: 使用 eval 对JavaScript声明求值

下面的例子使用eval() 对str字符串求值。这个字符串包含了JavaScript声明,如果x等于5,就打开一个Alert 对话框,然后对 z 赋值。 否则就对z赋值0。 当第二个声明被执行, eval 将会将str表达式执行,然后会对声明集合求值,并将返回值赋值给z。

var str = "if (x == 5) {alert('z is 42'); z = 42;} else z = 0; ";
document.write("<P>z is ", eval(str));

返回值

eval 将会返回对最后一个表达式的求值结果。

var str = "if ( a ) { 1+1; } else { 1+2; }";
var a = true;
var b = eval(str);  // returns 2 
alert("b is : " + b);
a = false;
b = eval(str);  // returns 3
alert("b is : " + b);

See also

文档标签和贡献者

标签: 
 此页面的贡献者: Binly42, ziyunfei, fscholz, qianjiahao, teoli, huguowei, Mgjbot, Laser
 最后编辑者: Binly42,