简体   繁体   English

删除非限定标识符时,严格模式语法错误背后的动机是什么?

[英]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: 规格:

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

相关问题 运行 angular 8 生产时:在严格模式下删除不合格的标识符 - When run angular 8 production: Delete of an unqualified identifier in strict mode (如果函数体处于严格模式,函数eval(){})会抛出语法错误? - (function eval () {}) throws a syntax error if function body is in strict mode? 如何在没有严格模式的情况下执行 deno? 错误:未捕获的 SyntaxError:标识符“列表”已被声明 - How to execute deno without strict mode ? Error: Uncaught SyntaxError: Identifier 'list' has already been declared 在严格模式下使用删除操作删除对象条目 - Deleting an Object Entry with delete in Strict Mode 在严格模式下使用this.inherited(arguments)时出现DOJO错误 - DOJO error when using this.inherited(arguments) in strict mode 错误:使用反应时出现意外的严格模式保留字 - error: Unexpected strict mode reserved word when using react 语法错误:意外的标识符 - Syntax Error: Unexpected Identifier 什么时候不要在 JavaScript 中使用“严格模式”? - When to NOT use "strict mode" in javascript? 打字稿文件语法错误的笑话测试:“接口是严格模式下的保留字” - Jest test on typescript file syntax error: "interface is a reserved word in strict mode" 将“eval”定义为Function构造函数调用的形式参数。 不应该在严格模式代码中抛出语法错误吗? - Defining “eval” as a formal parameter of a Function constructor invocation. Shouldn't that throw a syntax error in strict mode code?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM