JavaScript 变量声明有两种方式:显式和隐式。显式声明就是指用 var、let、const 等关键字进行的声明,而隐式声明则发生在赋值语句中。
//显示声明
var str = 'test'
//隐式声明
num = 100
对于显式声明大家都很理解,对于隐式声明 JavaScript 逻辑如下:
-
如果变量没有声明过,则先声明变量并立即赋值;
-
如果变量已经声明过,则该语句是赋值语句;
当一个被声明的变量、常量或符号,去绑定一个数据时,其实还有其他几个方面的含义:
-
逻辑作用域「变量的使用范围」
-
数据生存周期「内存中变量的创建、存活、销毁」
-
数据的可写性「是否可更改」
下面的语义都存在着隐式或显示的数据声明,它们都有着各自的「作用域、值、可写性」
-
显示数据声明的语句 var、let、const、函数声明、类声明;
-
数种 for 语句、try…catch语句、赋值语句;
-
函数调用、new 运算符等语法的形式传参;
块级作用域的变量声明与一般 var 声明
- var 声明的变量,它的作用域是「当前函数、模块、全局」;而 let 声明的变量,作用域是在当前「代码块」,就是语句块。
- 在同一块代码里,var 可以多次声明变量名,在语法分析中与声明一次没有区别,后声明的会覆盖之前声明的变量,而 let 只能声明一次,用 let 去覆盖已经声明的变量会导致语法错误;
- 我们可以在 var 声明之前就使用其变量,因为变量会提升至代码块的最顶端,这个时候 var 声明的变量值为 undefined ,而我们使用 let 声明的变量,必须先声明后使用,let 声明之前就使用会触发异常,名词是「暂时性死区」
除上述三点外,var 和 let 的使用场景都一致。另外,我们在全局代码块使用 var 声明的变量,都会在全局对象 global 上注册一个属性。
再另外,常量声明 const 和类声明 class 在块级作用域上的特征与 let 声明是一致的。
var code = ‘javascript’
相当于
window.code = ‘javascript’
而用 let 声明的变量要遵从块级作用域规则,即使出现在全局代码块中,也只是声明的标识符,不作为全局对象上的属性。