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

qwe*_*ymk 86 javascript optimization eval function

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

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'));
Run Code Online (Sandbox Code Playgroud)

Ple*_*and 109

不,他们一样.

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

考虑以下代码:

function test1() {
    var a = 11;
    eval('(a = 22)');
    alert(a);            // alerts 22
}
Run Code Online (Sandbox Code Playgroud)

如果new Function('return (a = 22);')()使用,则局部变量a将保留其值.然而,一些JavaScript程序员如道格拉斯克罗克福德认为,也不应该使用,除非绝对必要,并evaling /使用Function上不受信任的数据构造是不安全的,不明智的.

  • "永远不应该使用"是如此广泛的声明.当任何输入超出您的控制范围时,不应该使用它.话虽如此,除了解析JSON之外,我从不需要使用它.但我在这里回答的问题似乎是有效用途,它涉及允许管理员生成最终用户可以使用的模板功能.在这种情况下,输入是由管理员生成的,因此可以接受 (9认同)
  • @GeorgeMauer:我认为你的意思是`eval('(function(){'+ code +'})')`,它将返回一个函数对象.[根据MDN](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function),"使用Function构造函数创建的函数不会为其创建上下文创建闭包;它们始终在窗口上下文中运行(除非函数体以"use strict";语句开头,在这种情况下,上下文是未定义的)." (5认同)
  • @Juan:Crockford的观点是eval经常被滥用(取决于你的观点),所以它应该被排除在"最佳实践"JavaScript之外.但是,我同意,当首次正确验证输入时,它对JSON或算术表达式解析等用途很有用.甚至Crockford也在他的JSON库json2.js中使用它. (3认同)

pal*_*wim 6

没有.

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

从原来的问题:

var evaluate = function(string) {
    return eval(string);
}
var func = function(string) {
    return (new Function( 'return (' + string + ')' )());
}
Run Code Online (Sandbox Code Playgroud)

这些将给你非常不同的结果:

evaluate('0) + (4');
func('0) + (4');
Run Code Online (Sandbox Code Playgroud)

  • 那么你根据他的实施捏造了你的榜样.如果他将评估实现为`return eval('('+ string +')');那么他们会产生相同的结果. (7认同)

Jua*_*des 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]');
}
Run Code Online (Sandbox Code Playgroud)

这个和新函数之间的最大区别在于函数不是词法范围的.所以它不能访问闭包变量和我的.