我无法理解为什么在严格模式下,当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
在非严格模式下使用 'd 变量声明一样?AFAIK 是eval
.