严格模式下的一个规则(请参见附录 C)说明:
当在严格模式代码中出现
delete
操作符时,如果其 UnaryExpression 是对变量、函数参数或函数名的直接引用,则抛出 SyntaxError。
因此,在以下代码中:
delete x
x
是一个引用(我知道这个是因为"评估标识符的结果始终是类型为引用的值")。但它是一个直接引用吗?
还有其他类型的引用吗?间接引用?如果没有,那么使用“直接”这个词有什么意义吗?
严格模式下的一个规则(请参见附录 C)说明:
当在严格模式代码中出现
delete
操作符时,如果其 UnaryExpression 是对变量、函数参数或函数名的直接引用,则抛出 SyntaxError。
因此,在以下代码中:
delete x
x
是一个引用(我知道这个是因为"评估标识符的结果始终是类型为引用的值")。但它是一个直接引用吗?
还有其他类型的引用吗?间接引用?如果没有,那么使用“直接”这个词有什么意义吗?
是的,有不同种类的引用
(EcmaScript §8.7)。例如成员运算符(EcmaScript §11.2.1)会导致引用,其基本值是baseReference
的值,我称之为“非直接”的。而“直接引用”将是标识符引用(EcmaScript §10.2.2.1),其中基本值是环境记录。
obj.prop
),它分为两个步骤解析:首先,在名称“obj”上执行标识符解析,这将解析为对对象的引用,然后,将创建一个新的引用,其基值是对象引用,名称为“prop”。是的,我想就是这样。 - Šime Vidas如果我理解正确,任何未定义为属性的内容都应该会出现错误。
以下内容应该会在控制台中抛出错误或失败:
(function(){ 'use strict'; var x = '2'; delete x; })();
(function(){ 'use strict'; delete arguments[0]; })('2');
this.x = true;
(在全局代码中,因此 this
是全局对象),现在 delete x
会抛出错误,但是 delete this.x
不会。因此,关键是你在删除表达式中如何引用它,而不是它是否是全局属性。 - Šime Vidas
delete x
时,Firefox 会抛出“SyntaxError:应用 'delete' 运算符到未经限定的名称已过时”的错误消息,这证实了您的说法。 - Šime Vidasdelete
旨在删除属性。尝试删除变量和其他直接引用是不适当的用法。默认情况下,JavaScript会忽略此不适当的用法,并仅返回false
。然而,在严格模式下,会抛出错误。当程序不当使用运算符(如delete
)时,应该抛出错误 - 因此,严格模式做得很对。理想情况下,这应该是默认行为,但这会破坏一些现有(遗留)程序。这就是为什么通过严格模式来选择此行为的原因。 - Šime Vidas