Javascript (函数eval(){})在函数体处于严格模式时抛出语法错误?
为什么这段代码会抛出错误Javascript (函数eval(){})在函数体处于严格模式时抛出语法错误?,javascript,theory,Javascript,Theory,为什么这段代码会抛出错误 // global non-strict code (function eval () { 'use strict'; }); 现场演示: 我们这里有一个命名函数表达式。我想明确指出,这个函数表达式出现在非严格代码中。如您所见,它的函数体是严格的代码 严格的模式规则如下: 相关的项目符号是这个(它是列表上的最后一个): 在严格模式代码中使用标识符eval或参数作为函数声明或函数表达式的标识符或形式参数名(13.1)是一种语法错误。尝试使用函数构造函数(15.3.2)动
// global non-strict code
(function eval () { 'use strict'; });
现场演示:
我们这里有一个命名函数表达式。我想明确指出,这个函数表达式出现在非严格代码中。如您所见,它的函数体是严格的代码
严格的模式规则如下:
相关的项目符号是这个(它是列表上的最后一个):
在严格模式代码中使用标识符eval或参数作为函数声明或函数表达式的标识符或形式参数名(13.1)是一种语法错误。尝试使用函数构造函数(15.3.2)动态定义此类严格模式函数将引发SyntaxError异常
请注意,此规则仅在函数声明/表达式本身出现在严格的代码中时才适用,而在我上面的示例中没有
但它仍然抛出一个错误?为什么?我猜它会抛出一个错误,因为函数eval会指向函数本身,而函数本身现在违反了严格模式。概述了在类似您的情况下应该发生什么:
- 如果任何标识符值在严格模式函数声明或声明的FormalParameterList中出现多次,则为SyntaxError 函数表达式
- 如果标识符“eval”或标识符“arguments”出现在严格模式的-FormalParameterList中,则为语法错误 FunctionDeclaration或FunctionExpression
- 如果标识符“eval”或标识符“arguments”作为严格模式的标识符出现,则为语法错误 函数声明或函数表达式。
eval
,因此,它是一个SyntaxError
。比赛结束了
要了解上述为何为“严格模式函数表达式”,请查看§13(函数定义)中的语义定义: 生产过程
函数表达式:
function
Identifieropt(
FormalParameterListopt){
FunctionBody}
评估结果如下:
使用严格的上下文调用的
使用strict
开头严格的
,而实际上整个函数表达式是严格的
。您的逻辑虽然直观,但不是JS的工作方式
如果您想知道ECMAscript为什么会以这种方式工作,那么它非常简单。假设我们有:
// look ma, I'm not strict
(function eval() {
"use strict";
// evil stuff
eval(); // this is a perfectly legal recursive call, and oh look...
// ... I implicitly redefined eval() in a strict block
// evil stuff
})();
谢天谢地,上面的代码将抛出,因为整个函数表达式标记为strict
好问题
因此,要找到问题的答案,您实际上需要查看以下步骤(具体来说,步骤3-5——增加了重点):
eval
的绑定(即,将某些内容分配给eval
),这是不允许的,因为在第4步之后,我们处于一个严格的环境中
请记住,该限制不适用于初始化新的eval
变量。将其用作赋值运算符的LeftHandSideExpression,这是函数声明过程的第5步
更新:
正如@DavidItarenco所指出的,这在第节中有明确的说明(除了第节中的隐式限制)。这里完全是猜测,但这可能与以下事实有关:在表达式中,具有名称的函数实例化表达式仅在函数内绑定该名称;换句话说,在内部,似乎有一种神奇的方法可以让
var
声明创建一个局部变量,该局部变量通过引用函数初始化。因此,就好像您试图在本地绑定全局符号“eval”。@这是一个很好的提示。我必须检查标准,以确定在该场景中到底发生了什么…您只使用Function eval(){'use strict';}得到相同的错误消息(SyntaxError:Function name可能不是eval或strict模式下的参数)代码>并且这不会产生语法错误:window.eval=function(){'use strict';}代码>锁定它。这正是这里发生的事情,所以在非严格代码中出现的函数表达式,但其函数体是严格代码,是一个“严格模式”