声明
在JavaScript中一共有六条声明用的语句,并且都用于声明一个或多个标识符。这里的标识符包括变量、常量等。
- let x …声明变量 x。不可在赋值之前读。
- const x …声明常量 x。不可写。
- var x …声明变量 x。在赋值之前可读取到 undefined 值。
- function x …声明变量 x。该变量指向一个函数。
- class x …声明变量 x。该变量指向一个类(该类的作用域内部是处理严格模式的)。
- import …导入标识符并作为常量(可以有多种声明标识符的模式和方法)。
除了这六个语句之外,还有两个语句有潜在的声明标识符的能力,不过它们并不是严格意义上的声明语句(声明只是它们的语法效果)。这两个语句是指:
- for (var|let|const x …) …for 语句有多种语法来声明一个或多个标识符,用作循环变量。
- try … catch (x) …catch 子句可以声明一个或多个标识符,用作异常对象变量。
- 都意味着 JavaScript 将可以通过“静态”语法分析发现那些声明的标识符;
- 标识符对应的变量 / 常量“一定”会在用户代码执行前就已经被创建在作用域中。
从读取值到赋值
var申明的标识符约定称为“变量声明(varDelcs)”, 而“let/const”标识符则称为“词法声明(lexicalDecls)”。JavaScript 环境在创建一个“变量名(varName in varDecls)”后,会为它初始化绑定一个 undefined 值,而”词法名字(lexicalNames)”在创建之后就没有这项待遇,所以它们在缺省情况下就是“还没有绑定值”的标识符。
- 函数是按 varDecls 的规则声明的;
- class的内部是处于严格模式,所以它的名字是按照let来处理的;
- import导入的名字是按照const来处理的 所以,所有的声明本质上只有三种处理模式:var 变量声明、let 变量声明和 const 常量声明
赋值
在JavaScript中,赋值的严格语法表达是:
LeftHandSideExpression < = | AssignmentOperator > AssignmentExpression
所以在 JavaScript 中,一个赋值表达式的左边和右边其实“都是”表达式!
变量声明在引擎的处理上被分成两个部分:一部分是静态的、基于标识符的词法分析和管理,它总是在相应上下文的环境构建时作为名字创建的;另一部分是表达式执行过程,是对上述名字的赋值,这个过程也称为绑定。