我无法理解为什么在严格模式下,当delete
用于非限定标识符时会发生语法错误。
在大多数情况下,它是有意义的......如果您使用var
关键字以常规方式声明变量,然后尝试对它们使用delete
,则在非严格模式下会默默地失败,因此在这些情况下严格模式失败并出错是有道理的。
但是,有些情况下无法删除 限定的标识符:
(function() {
// "use strict";
var obj = Object.create({}, { bloop: { configurable: false } });
delete obj.bloop; // throws TypeError in strict mode, silently fails in non-strict.
console.log('bloop' in obj); // true
}());
严格模式必须在此处执行运行时检查,因为遇到此类错误时会抛出TypeError。在某些情况下,可以成功删除非严格模式下的非限定标识符......
// "use strict";
window.bar = 6;
console.log(typeof bar); // number
delete bar; // works in non-strict, syntax error in strict!
console.log(typeof bar); // undefined
事实上,根据我的理解,您是否可以删除内容(在非严格模式下)取决于内部[[Configurable]]
属性,并且与限定标识符无关。据我所知,在严格模式下无法删除(作为本地VO的属性) 可配置的非全局变量:
(function() {
// "use strict";
eval('var foo = 5;');
console.log(typeof foo); // number
delete foo; // works in non-strict, SyntaxError in strict.
console.log(typeof foo); // undefined
}());
所以,我的问题是,在非限定标识符上使用delete
时抛出一个SyntaxError有什么意义呢,如果属性不可配置,TypeError会抛出?这似乎是一个不必要的限制,在某些情况下似乎没有任何解决方法,除了不使用严格模式(第三个例子)。任何人都可以解释这个决定背后的动机吗?
更新:我刚才意识到我忽略了这样一个事实:直接eval
调用在严格模式下有自己的范围,而不是调用函数的范围,所以在第三个例子中foo
不会在严格模式下定义。无论如何,运行时检查仍然会捕获这一点,但它提出了一个侧面问题:是否无法在严格模式下使用可配置的局部变量,就像在非严格模式下使用eval
'变量声明一样? AFAIK是eval
的少数合法用途之一。
答案 0 :(得分:6)
您正在谈论规范的Section 11.4.1, paragraph 5.a.:
- 否则,ref是对环境记录绑定的引用,所以
醇>
一个。如果IsStrictReference(ref)为true,则抛出SyntaxError异常 湾让绑定成为GetBase(ref)。
C。返回调用DeleteBinding具体绑定方法的结果,提供GetReferencedName(ref)作为参数。
您所谓的“非限定标识符”正式命名为“环境记录绑定”。
现在,问你的问题。为什么在5.c.时抛出一个SyntaxError。反正会失败吗?我想你自己回答了!
严格模式必须在此执行运行时检查,因为遇到此情况时会抛出 。
没错。但快速失败总是更好。因此,当有可能检测到SyntaxError(解析时间)时,应该抓住这个机会。
为什么呢?如果发生错误,它可以帮您省去修复应用程序的麻烦。考虑可能会立即向您显示错误的IDE,而不是几小时的调试 此外,这些限制对于优化的JIT编译器可能是有利的。
答案 1 :(得分:2)
如果要在严格模式下删除对象。您必须明确提及有关属性访问权限。另请注意,您如何调用该函数非常重要。如果new
运算符未被使用this
在use strict
下未定义,则您无法使用以下方法。
例如:
'use strict' function func(){ var self = this; self.obj = {}; self.obj.x = 'y' console.log(self.obj); delete self.obj // works // delete obj // doesn't work console.log(self.obj); } var f = new func();
要删除函数(闭包)之外的对象,您必须调用
// same code as above delete f.obj