删除非限定标识符时出现严格模式语法错误背后的动机
Motive behind strict mode syntax error when deleting an unqualified identifier?
我很难理解为什么在严格模式下,当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
为数不多的合法用途之一。
您正在谈论规范的第 11.4.1 节第 5.a 段:
- 否则,ref 是对环境记录绑定的引用,因此
一个。如果 IsStrictReference(ref( 为 true,则抛出 SyntaxError 异常。
b.让绑定是 GetBase(ref(。
c.返回调用绑定的 DeleteBinding 具体方法的结果,提供 GetReferencedName(ref( 作为参数。
您所谓的"非限定标识符"正式命名为"环境记录绑定"。
现在,回答你的问题。当 5.c. 无论如何都会失败时,为什么要抛出 SyntaxError?我想你自己回答了!
严格模式必须在此处执行运行时检查,因为遇到此问题时会引发 TypeError。
没错。但快速失败总是更好。因此,当有机会检测到 SyntaxError 时(在解析时(,应该抓住这个机会。
为什么?如果发生错误,它省去了修复应用程序的麻烦。考虑一下可能会立即显示错误的 IDE,而不是数小时的调试。
此外,此类限制可能对优化的 JIT 编译器有利。
如果要在严格模式下删除对象。您必须明确提及属性访问权限。另请注意,如何调用函数很重要。如果不使用运算符new
则this
在 use strict
下未定义,并且不能使用以下方法。例:
"使用严格"函数 func(({ var self = this; self.obj = {}; self.obj.x = 'y' console.log(self.obj(; 删除自我.obj//作品 删除 obj//不起作用 console.log(self.obj(;}var f = new func((;
要删除函数(闭包(之外的对象,您必须像
与上述代码相同删除 F.obj
- Javascript,访问一个主要对象模块模式中的每个对象
- 是否有任何snippet或jQuery插件可以列出easylist.txt模式匹配的DOM中的所有元素
- 试图在引导模式内动态生成图表,得到offsetWidth错误
- 同位素库错误:未捕获错误无布局模式包装生产线8
- 铬:“;未捕获的语法错误:意外的标记:"
- jQuery语法添加了var
- Javascript未捕获语法错误意外的标识符错误
- 在DOM中查找一个模式并替换它's的内容使用jquery
- emacs:我可以停止js2模式吗's语法检查
- 正确使用模块模式语法
- 删除非限定标识符时出现严格模式语法错误背后的动机
- 引导模式委托偶数类型语法
- Javascript es6类语法模式
- 使用变量作为模式的正则表达式的Javascript语法
- jQuery JavaScript不能在Wordpress上工作,对无冲突模式语法感到困惑
- Javascript模式中的语法错误
- 这个javascript语法/模式是什么意思
- 在Emacs js2模式下查找语法警告的热键
- 模型视图控制器-Javascript可以构建这种MVC模式或语法糖
- 简单的JavaScript XPath语法模式验证器(无上下文)