Function和new Function之间的区别

8

我有时看到人们这样写 Function('alert("hi")') 有时候他们写成 new Function('alert("hi")')

这两种方式有什么不同吗?


4
除非特殊情况,否则你不应该做其中的任何一件事。 - SLaks
1
请参见https://dev59.com/MHRC5IYBdhLWcg3wMd9S。 - Rafe Kettler
1
它们相似之处在于它们都是“DoingItWrong”的实例(暗示使用eval,而function() { alert("hi"); }同样有效?这是什么鬼啊,人类)。 - user395760
请勿使用带参数的函数构造器。谢谢。 - Raynos
1
@Raynos 那么它应该在什么时候使用? - user594284
1
@user:在极其罕见的情况下。如果你不得不问,那就不要去做。 - SLaks
4个回答

5

规范(第127页)指出它们是相同的。

15.3.1.1 函数 (p1, p2, … , pn, body)

当使用一些参数 p1、p2、…、pn 和 body(其中 n 可能为 0,即没有“p”参数,而且 body 也可能未提供)调用 Function 函数时,将执行以下步骤:

  1. 创建并返回一个新的函数对象,就好像在新的表达式中使用了标准内置构造函数 Function 和相同的参数(15.3.2.1)。

但是,您应该尽量避免使用 Function 构造函数。
它需要对您传递给它的字符串进行 evaleval 是邪恶的,而且速度也很慢。


啊!请提供一个指向规格的扇区/页码链接。 - Raynos
@SLaks 这是他们的错,因为他们没有在 URL 前面加上 #15.3。 - Raynos
@Raynos:这是一个PDF文件。据我所知,如果他们尝试的话,他们无法做到这一点。 - SLaks
@SLaks:不用谢。@CMS就在前几天的评论中提到了它。 - user113716
@Raynos:可惜,这就是我的能力极限了。引用别人的辛勤工作。;o) - user113716

1

new Function 只有一种用法。就是这个:

var constructor = new Function;

// then this 

constructor.prototype = { 
    //...  stuff
};

// OR

constructor.prototype = new someOtherThing;

// then

var obj = new constructor;

如果你想创建一个只使用继承的空构造函数对象构造器,基本上可以使用new Function

如果你想让一个函数执行任何操作,那么根本不要使用Function


1
@SLaks 这是一个风格问题。但这仍然是 new Function 的唯一有效用法。 - Raynos
3
@Raynos,我认为“Function”构造函数比“eval”更安全,因为它使用全新的变量/词法环境(您只能访问在全局范围内或函数本身中声明的标识符,而不能访问调用者的作用域)。 - Christian C. Salvadó
@CMS:是的,在意识到这一点之后,我做了笔记,然后决定删除。我的例子非常糟糕。 :o) - user113716
Raynos:那完全是我的错。他指出了我示例中的严重缺陷,所以我将其删除了。对于造成的混淆,我感到抱歉。我认为这个示例说明了@CMS所说的内容。 - user113716
@patrickdw 那个例子是安全的,因为在该函数上调用new会创建一个唯一的this作用域。这更清楚地说明了这一点:http://jsfiddle.net/Raynos/GJXAk/4/。@CMS 虽然感谢你的解释。 - Raynos
显示剩余6条评论

0

回答你的问题:根据ECMA5规范Function(...)new Function(...)是完全相同的。

关于何时何地应该使用它,答案是很少。我知道有一种情况我们使用了Function(...),那就是在创建自定义ASP.NET服务器控件时。我们经常有类似于[ServerControl].OnClientClick的东西,它指定了一个JavaScript字符串(在服务器端),当单击事件发生时应在客户端运行。然后我们将JS字符串放入一个函数中,并在满足特定条件时调用它。这也允许我们调用.call(...)函数来设置上下文并传递事件参数,就像从onclick属性调用JS一样。


0

作为函数调用函数构造器(不使用new运算符)与作为构造器调用它具有相同的效果。

这意味着如果您这样做,代码是相同的:

var result1 = new Function('a', 'b', 'return a + b')
var result2 = Function('a', 'b', 'return a + b')

result1和result2是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接