删除非限定标识符时,严格模式语法错误背后的动机是什么? [英] Motive behind strict mode syntax error when deleting an unqualified identifier?

查看:113
本文介绍了删除非限定标识符时,严格模式语法错误背后的动机是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解为什么在严格模式下,当在非限定标识符上使用 delete 时会发生语法错误。

I'm having trouble understanding why, in strict mode, a syntax error occurs when delete is used on an unqualified identifier.

在大多数情况下,如果你使用 var 关键字以通常的方式声明变量,然后尝试使用删除,在非严格模式下它会无声地失败,因此在这些情况下严格模式失败并出错是有意义的。

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.

但是,有些情况下无法删除 限定的标识符:

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

}());

严格模式必须在这里进行运行时检查,因为遇到这种情况时会抛出TypeError。在某些情况下,可以成功删除非严格模式下的非限定标识符...

Strict mode must do a runtime check here, because a TypeError is thrown when this is encountered. 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

事实上,根据我的理解,你是否可以删除东西(非严格模式)取决于内部 [[Configurable]] 属性,并且与限定标识符无关。据我所知,在严格模式下无法删除非全局变量(作为本地VO的属性) 可配置:

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. 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:

(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

}());

所以,我的问题是,在使用时抛出SyntaxError有什么意义?删除对一个非限定标识符,如果该属性不可配置,那么无论如何都会抛出TypeError?这似乎是一个不必要的限制,在某些情况下似乎没有任何解决方法,除了不使用严格模式(第三个例子)。任何人都可以解释这个决定背后的动机吗?

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? 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?

更新:我刚才意识到我忽略了直接 eval 调用在严格模式下有自己的作用域,而不是调用函数的作用域,所以在第三个例子中 foo 不会在严格模式下定义。无论如何,运行时检查仍然会捕获这个,但它提出了一个侧面问题:是否无法在严格模式下使用可配置的局部变量,就像我们使用 eval 'd一样变量声明在非严格? AFAIK是 eval 的少数合法用途之一。

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. 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? AFAIK that was one of the few legitimate uses of eval.

推荐答案

您在谈论第11.4.1节,第5.a.段的规格:



  1. 否则,ref是对环境记录绑定的引用,所以

    a。如果IsStrictReference(ref)为true,则抛出一个SyntaxError异常。

    b。让绑定成为GetBase(ref)。

    c。返回调用DeleteBinding具体绑定方法的结果,提供GetReferencedName(ref)作为参数。


你所谓的非限定标识符正式命名为环境记录绑定。

What you called "unqualified identifiers" is officially named "Environment Record binding".

现在,问你的问题。为什么在5.c.时抛出一个SyntaxError。反正会失败吗?我想你自己回答了这个问题!

Now, to your question. Why throw a SyntaxError when 5.c. would fail anyway? I think you answered it yourself!


严格模式必须在这里进行运行时检查,因为抛出了TypeError遇到这种情况时

Strict mode must do a runtime check here, because a TypeError is thrown when this is encountered.

这是对的。但快速失败总是更好。因此,当有可能检测到SyntaxError(解析时间)时,应该采取这种机会。

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.

为什么?如果发生错误,它可以帮您省去修复应用程序的麻烦。考虑可能会立即向您显示错误的IDE,而不是几小时的调试。

此外,这些限制可能对优化的JIT编译器有利。

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.
Also, such restrictions may be advantageous for optimized JIT compilers.

这篇关于删除非限定标识符时,严格模式语法错误背后的动机是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆