§13.1概述了在您的情况下应该发生的情况:
- 如果任何 Identifier 值在严格模式 FunctionDeclaration 或 FunctionExpression 的 FormalParameterList 中出现多次,则为 SyntaxError。
- 如果标识符“eval”或标识符“arguments”出现在严格模式 FunctionDeclaration 或 FunctionExpression 的 FormalParameterList 中,则为 SyntaxError。
- 如果标识符“eval”或标识符“arguments”作为严格模式 FunctionDeclaration 或 FunctionExpression 的标识符出现,则为 SyntaxError。
强调我的。您的严格模式函数的标识符是eval
,因此,它是SyntaxError
. 游戏结束。
要了解上述为什么是“严格模式函数表达式”,请查看第 13 节(函数定义)中的语义定义:
产生式
FunctionExpression : function
Identifier opt (
FormalParameterList opt ) {
FunctionBody }
的评估如下:
- 返回创建一个新的函数对象的结果,如 13.2 中指定的,参数由 FormalParameterListopt 指定,主体由 FunctionBody 指定。传入正在运行的执行上下文的 LexicalEnvironment 作为 Scope。如果 FunctionExpression 包含在严格代码中或其 FunctionBody 是严格代码,则传入 true 作为 Strict 标志。
强调我的。上面显示了函数表达式(或声明)如何变得严格。它所说的(用简单的英语)是FunctionExpression在strict
两种情况下:
- 它是从
use strict
上下文中调用的。
- 它的函数体以
use strict
.
您的困惑源于认为只有函数体是strict
,而实际上整个函数表达式是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
.