这两个功能在幕后做同样的事吗? (在单一陈述函数中)
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'));
答案 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)
没有
在您的更新中,对evaluate
和func
的调用会产生相同的结果。但是,他们绝对不是“在幕后做同样的事情”。 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将返回一个返回字符串的函数。