【问题标题】:Why is 'let' allowed as a variable name? [duplicate]为什么允许“让”作为变量名? [复制]
【发布时间】:2020-11-22 07:59:10
【问题描述】:

我想知道是否有人可以将聚光灯指向我刚刚发现的一些奇怪行为。因此,我在节点 REPL 中工作,在将代码粘贴到模块中之前运行代码,并且我打错了“let = 5”(好吧,没有完全填写该行)。我预计这会出错,但 REPL 接受了它,我可以通过表达式结果和 console.logs 看到该值。所以我开始修修补补。我知道在 REPL 中,没有 let/const/var 的变量被认为是全局的,但我想知道的是,为什么 REPL 允许我们像这样分配 let?下面我列出了我尝试过的东西(仅在 REPL 中,未在模块脚本中尝试过)。

let = 5; //works
var = 5; //SyntaxError: Unexpected token "="
const = 5; //SyntaxError: Unexpected token "="

let let = 5; //SyntaxError: let is disallowed as a lexically bound name
var let = 5; //works
const let = 5; //SyntaxError: let is disallowed as a lexically bound name

let var = 5; //SyntaxError: Unexpected token "var"
var var = 5; //SyntaxError: Unexpected token "var"
const var = 5; //SyntaxError: Unexpected token "var"

let const = 5; //SyntaxError: Unexpected token "const"
var const = 5; //SyntaxError: Unexpected token "const" 
const const = 5; //SyntaxError: Unexpected token "const"  

那么为什么let = 5var let = 5 在逻辑上(至少对我而言)所有这些语句都应该是语法错误时起作用?

编辑要补充一点,let 在分配后用于分配变量时仍然有效。例如

let = 5; 
let test = {}; 
console.log(let,test)

有效,并显示5 {}

【问题讨论】:

    标签: javascript variable-assignment


    【解决方案1】:

    constlet 已在ECMA2011 中作为未来保留字 引入。

    ECMA2011 - 引入 constlet 作为未来保留字

    7.6.1.2 未来保留字

    以下词在提议的扩展中用作关键字,并且 因此保留以允许未来采用的可能性 这些扩展名。

    FutureReservedWord ::

    • 枚举
    • 扩展
    • 超级
    • 常量
    • 导出
    • 导入

    以下标记也被认为是 FutureReservedWords 当它们出现在严格模式代码中时(见 10.1.1)。发生 在任何上下文中,严格模式代码中的任何这些标记 FutureReservedWord 的出现会产生错误,必须 也会产生等效的错误:

    • 实现
    • 私人
    • 公开
    • 产量
    • 界面
    • 受保护
    • 静态

    ECMA2012 - 批准的关键字

    后来在ECMA2012 中,这两个词都被添加为关键字,不能用作标识符

    7.6.1.1 关键字

    以下标记是 ECMAScript 关键字,不得用作 标识符在 ECMAScript 程序中。

    关键字 ::

    • 中断
    • 删除
    • 导入
    • 这个
    • 案例
    • 投掷
    • 赶上
    • 其他
    • instanceof
    • 试试
    • 导出
    • 类型
    • 继续
    • 终于
    • var
    • 常量
    • 返回
    • 无效
    • 调试器
    • 功能
    • 超级
    • 同时
    • 默认
    • 如果
    • 切换

    const 用作 identifier 在每种模式下都会引发错误,let 只会在严格模式下引发错误,现在使用您的示例仍然是这种情况:

    有效

    使用let 作为没有严格模式的标识符。

    (function(){
        //REM: Works
        var let = 5;
        console.log(let);
      })();

    无效

    使用const作为没有严格模式的标识符。

    (function(){
        //REM: Throws an error
        var const = 5;
        console.log(const);
    })();

    在严格模式下使用letconst 作为标识符。

    (function(){
        'use strict';
        //REM: Throws an error
        var let = 5;
        console.log(let);
    })();

    (function(){
        'use strict';
        //REM: Throws an error
        var const = 5;
        console.log(const);
    })();

    所以从历史上看,ECMA 从一开始就对关键字constlet 更严格。虽然自 ECMA2012 以来let 可能不再用作标识符,但我认为由于向后兼容性,它被忽略了。

    Hereletconst 的最新规范。

    【讨论】:

      【解决方案2】:

      constlet 是最近添加到 JS 中的,但是在它们被添加之前 很长 时间const 是一个保留关键字(大概是基于它被认为是未来可能会添加到该语言中)。

      由于let 曾经是一个有效的变量名,这大概是为了向后兼容。

      【讨论】:

        猜你喜欢
        • 2020-06-15
        • 1970-01-01
        • 2019-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-07
        • 2015-03-01
        相关资源
        最近更新 更多