eval()和新的Function()是一样的吗?

时间:2011-01-05 00:38:33

标签: javascript function optimization eval

这两个功能在幕后做同样的事吗? (在单一陈述函数中)

var evaluate = function(string) {
    return eval('(' + string + ')');
}

var func = function(string) {
    return (new Function( 'return (' + string + ')' )());
}

console.log(evaluate('2 + 1'));
console.log(func('2 + 1'));

6 个答案:

答案 0 :(得分:104)

不,他们相同。

  • eval()将字符串计算为当前执行范围内的JavaScript表达式,并且可以访问局部变量。
  • new Function()将存储在字符串中的JavaScript代码解析为函数对象,然后可以调用该函数对象。它无法访问局部变量,因为代码在单独的范围内运行。

考虑以下代码:

function test1() {
    var a = 11;
    eval('(a = 22)');
    alert(a);            // alerts 22
}

如果使用new Function('return (a = 22);')(),则局部变量a将保留其值。然而,像Douglas Crockford这样的一些JavaScript程序员认为neither should be used除非absolutely necessary,并且对不受信任的数据进行evaling /使用Function构造函数是不安全和不明智的。

答案 1 :(得分:6)

没有

在您的更新中,对evaluatefunc的调用会产生相同的结果。但是,他们绝对不是“在幕后做同样的事情”。 func函数创建一个新函数,但随后立即执行它,而evaluate函数只是当场执行代码。

从最初的问题:

var evaluate = function(string) {
    return eval(string);
}
var func = function(string) {
    return (new Function( 'return (' + string + ')' )());
}

这些会给你带来截然不同的结果:

evaluate('0) + (4');
func('0) + (4');

答案 2 :(得分:6)

new Function创建一个可以重复使用的函数。 eval只执行给定的字符串并返回最后一个语句的结果。当您尝试创建使用Function来模拟eval的包装函数时,您的问题被误导了。

他们在幕后分享一些代码是真的吗?是的,非常有可能。完全相同的代码?不,当然。

为了好玩,这是我自己使用eval创建函数的不完美实现。希望它能为这种差异带来一些启示!

function makeFunction() {
  var params = [];
  for (var i = 0; i < arguments.length -  1; i++) {
    params.push(arguments[i]);
  }
  var code = arguments[arguments.length -  1];


 // Creates the anonymous function to be returned
 // The following line doesn't work in IE
 // return eval('(function (' + params.join(',')+ '){' + code + '})');
 // This does though
 return eval('[function (' + params.join(',')+ '){' + code + '}][0]');
}

这个和新函数的最大区别在于函数不是词法范围的。因此,它无法访问闭包变量,我的也是。

答案 3 :(得分:2)

如果你的意思是,它会产生相同的结果,那么是的......但只是对eval(又名“评估这一串JavaScript”)会更简单。

编辑下面:

这就像说......这两个数学问题是一样的:

1 + 1

1 + 1 + 1 - 1 + 1 - 1 * 1/1

答案 4 :(得分:1)

在那个例子中,结果是一样的,是的。两者都执行您传递的表达式。这就是他们如此危险的原因。

但他们在风格背后做了不同的事情。涉及new Function()的幕后花絮,会根据您提供的代码创建一个匿名函数,该函数在调用函数时执行。

在调用匿名函数之前,传递给它的JavaScript在技术上不会执行。这与立即执行代码的eval()形成对比,并且不会基于它生成函数。

答案 5 :(得分:1)

只想指出这里示例中使用的一些语法及其含义:

 var func = function(string) {
     return (new Function( 'return (' + string + ')' )());
 }

注意函数(...)()的末尾有“()”。此语法将导致func执行新函数并返回字符串而不是返回字符串的函数,但如果使用以下内容:

 var func = function(string) {
     return (new Function( 'return (' + string + ')' ));
 }

现在func将返回一个返回字符串的函数。