使用“let”作为变量名不会在 google v8 中引发任何错误

IT技术 javascript node.js google-chrome ecmascript-6 v8
2021-03-10 21:36:31

我正在 chrome 开发者控制台中编写一些随机代码。令我惊讶的是,chrome 允许我将其let用作变量名,这let与保留关键字完全错误我需要了解为什么会发生这种情况。

场景:

var const = 78 //throws an error as expected

var function = 46 //throws an error as expected

var let = 56 //didn't throw an error :O

let //prints 56, which is wrong because 'let' is a keyword

let ab = 90

ab //prints 90 as expected

该缺陷存在于node. 但是,当我在Babel REPL 中尝试时,它抛出了一个错误。

我认为这与 Google v8 有关

3个回答

可以在Mohsen Azimi 的这篇文章中找到关于背后的推理的一篇很好的文章这是它的快速摘要。

以下关键字在 JavaScript 规范中定义为FutureReservedWord

implements     interface   let       package    private
protected      public      static    yield

在正常模式下,这些可以用作变量名而不会出错;但是,在严格模式下,它们被视为保留字,并会抛出以下错误:

SyntaxError: Cannot use the reserved word 'let' as a variable name in strict mode.

这是为了使 ES2015 之前的代码不会被破坏——如果有人let在遗留应用程序中命名了很多变量,如果 JS 规范突然破坏了一切,他们可能会不高兴。

干净的。我仍然建议 v8 人员添加deprecated警告以修复遗留应用程序。
2021-04-20 21:36:31
@loganfsmyth:是的,我忘记了module默认使用严格模式。
2021-04-28 21:36:31
@PraneshRavi:是的,我总是发现"use strict";这样的解决方案有点笨拙,尤其是现在 JS 应用程序往往被分成许多单独的文件。
2021-05-05 21:36:31
Javascript 就是这样,它并没有被弃用,只是在严格的代码中是不允许的。一旦 ES6 module落地,大多数新代码最好使用它们,并且默认情况下它们是严格的,但是如果您use strict在非 ES6 module中忘记,设置 linting 规则来提醒您也相对容易
2021-05-10 21:36:31

出于兼容性原因,仅在严格模式下禁止使用保留的 ES6 关键字。

Babel(通过严格模式插件)默认使用严格模式。在浏览器或 Node 中,您可以通过"use strict";在文件或函数的开头添加来隐式设置严格模式

运行以下代码片段将在 Chrome 中按预期抛出错误:

"use strict";
var let = 43;
// Throws: Uncaught SyntaxError: Unexpected strict mode reserved word

这是一种不断发展的语言的乐趣。

简短的版本是const在 ECMAScript 第一版中列为“未来保留字”,这意味着虽然它没有任何意义(当时),但它不能用于标识符。(当然,function一直是保留字。)但let既不是保留字也不是未来保留字,因此它可以用于标识符(并且曾经是)。直到第 5 版let才被确定为未来的保留字,然后才在新的严格模式中添加了 ES5。(您的示例在严格模式下不起作用。)因为let没有保留,它可能被广泛使用的代码中使用,并且不能在 ES2015 中追溯成为纯粹的保留字。因此,它仍然是一个有效的标识符(在松散模式下)。解析器必须根据上下文确定它是声明还是标识符。(这有一个有趣的结果,在松散模式下,忘记在let不是语法错误之后输入标识符let = 42;工作得很好——即使let没有在任何地方声明[感谢我称之为隐式全局的恐怖]。这些是总是使用严格模式的好理由[因为let在严格模式下不能是标识符,而且严格模式没有隐式全局变量]。)

JavaScript 也有上下文保留字。async是一个有效的标识符(即使在严格模式下,甚至在async函数内部!),它只在以前它会是标识符语法错误的地方有特殊含义:

// Since `blah function` here is a syntax error:
blah function foo() {
}
// ...no valid code would have an identifier in that position, so it was possible
// to add an `async` modifier:
async function foo() {
}

await是一个有效的标识符(即使在严格模式下),除非它在async函数内;那么它是一个保留字。这是可能的,因为async之前不存在函数await,因此不可能存在async用作await标识符函数同样,yield只是生成器函数内部的保留字。