[英]Motive behind strict mode syntax error when deleting an unqualified identifier?
I'm having trouble understanding why, in strict mode, a syntax error occurs when delete
is used on an unqualified identifier. 我无法理解为什么在严格模式下,当对非限定标识符使用
delete
时会发生语法错误。
In most cases, it makes sense... if you are declaring variables in the usual way with the var
keyword, and then trying to use delete
on them, in non-strict mode it would silently fail, so it makes sense for strict mode to fail with an error in those cases. 在大多数情况下,它是有道理的...如果你用
var
关键字以通常的方式声明变量,然后尝试对它们使用delete
,在非严格模式下它会默默地失败,所以对于严格模式是有意义的在这些情况下失败并出错。
However, there are cases where you can't delete identifiers that are qualified: 不过,也有,你不能删除合格标识的情况下:
(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
}());
Strict mode must do a runtime check here, because a TypeError is thrown when this is encountered. 严格模式必须在此处执行运行时检查,因为遇到此类型时会引发TypeError。 There are also cases where you can successfully delete unqualified identifiers in non-strict mode...
在某些情况下,您可以在非严格模式下成功删除非限定标识符...
// "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
In fact, to my understanding, whether or not you can delete things (in non-strict mode) depends on the internal [[Configurable]]
property, and has nothing to do with qualified identifiers. 事实上,根据我的理解,您是否可以删除内容(在非严格模式下)取决于内部
[[Configurable]]
属性,并且与限定标识符无关。 As far as I can tell, there is no way in strict mode to delete non-global variables that (as properties of the local VO) are 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
}());
So, my question is, what's the point of throwing a SyntaxError when using delete
on an unqualified identifier, when the TypeError would throw anyway if the property is not configurable? 所以,我的问题是,当在非限定标识符上使用
delete
时抛出一个SyntaxError有什么意义,如果该属性不可配置,那么无论如何都会抛出TypeError? This seems like an unnecessary restriction, and in some cases there doesn't seem to be any workaround other than not using strict mode (third example). 这似乎是一个不必要的限制,在某些情况下似乎没有任何解决方法,除了不使用严格模式(第三个例子)。 Can anyone explain the motivation behind this decision?
谁能解释这个决定背后的动机?
Update: I just realized that I was overlooking the fact that direct eval
calls have their own scope in strict mode, instead of the calling function's scope, so in the third example foo
would not be defined under strict mode. 更新:我刚刚意识到我忽略了这样一个事实,即直接
eval
调用在严格模式下有自己的范围,而不是调用函数的范围,所以在第三个例子中, foo
不会在严格模式下定义。 Anyway, the runtime check would still catch this, but it raises a side question: Is there no way to have configurable local variables in strict mode, as we do with eval
'd variable declarations in non-strict? 无论如何,运行时检查仍然会捕获这一点,但它提出了一个侧面问题:是否无法在严格模式下使用可配置的局部变量,就像我们在非严格模式中使用
eval
变量声明一样? AFAIK that was one of the few legitimate uses of eval
. AFAIK是
eval
的少数合法用途之一。
You are talking about Section 11.4.1, paragraph 5.a. 你在谈论第11.4.1节,第5.a节。 of the specs:
规格:
- Else, ref is a Reference to an Environment Record binding, so
否则,ref是对环境记录绑定的引用,所以
a.一个。 If IsStrictReference(ref) is true, throw a SyntaxError exception.
如果IsStrictReference(ref)为true,则抛出SyntaxError异常。
b.湾 Let bindings be GetBase(ref).
让绑定成为GetBase(ref)。
c.C。 Return the result of calling the DeleteBinding concrete method of bindings, providing GetReferencedName(ref) as the argument.
返回调用DeleteBinding具体绑定方法的结果,提供GetReferencedName(ref)作为参数。
What you called "unqualified identifiers" is officially named "Environment Record binding". 你所谓的“不合格标识符”正式命名为“环境记录绑定”。
Now, to your question. 现在,问你的问题。 Why throw a SyntaxError when 5.c.
为什么在5.c.时抛出一个SyntaxError。 would fail anyway?
反正会失败吗? I think you answered it yourself!
我想你自己回答了!
Strict mode must do a runtime check here, because a TypeError is thrown when this is encountered .
严格模式必须在此处执行运行时检查 ,因为遇到此类型时会引发TypeError。
That's right. 那就对了。 But it's always better to fail fast.
但快速失败总是更好。 So, when there is a chance of detecting a SyntaxError (at parse time ), that opportunity should be taken.
因此,当有可能检测到SyntaxError(在分析时 )时,应该采取这种机会。
Why? 为什么? It saves you the trouble of fixing your app if an error occurs.
如果发生错误,它可以帮您省去修复应用程序的麻烦。 Think about IDEs that may show you the error right away, as opposed to hours of debugging.
考虑可能会立即向您显示错误的IDE,而不是数小时的调试。
Also, such restrictions may be advantageous for optimized JIT compilers. 而且,这种限制对于优化的JIT编译器可能是有利的。
If you want to delete object in strict mode. 如果要在严格模式下删除对象。 You have to explicitly mention about the property access.
您必须明确提及有关属性访问权限。 Also note that, how you call the function is important.
另请注意,您如何调用该函数非常重要。 If
new
operator isn't used this
is undefined under use strict
, and you cant use the below method. 如果
new
未使用运营商this
是在不确定的use strict
,你不能使用下面的方法。 Example: 例:
'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();
For deleting object outside of the function(closure), you will have to call like 要删除函数(闭包)之外的对象,您必须调用
// same code as above delete f.obj
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.