初步了解 let 用法后,觉得有必要总结一下 JS 中三种变量声明的区别,不然很容易混淆。(let & const 为 ES6 增加的声明命令)
var
var 声明变量时,可以同时初始化变量。
使用 var 语句声明的变量的作用域是当前执行位置的上下文:一个函数的内部(声明在函数内)或者全局(声明在函数外)。
注意:var 声明变量的作用域只能是全局域或者是函数域,而不能是块级域。 这是 var 和 let 声明变量的作用域最大的不同。给一个非声明变量赋值会隐式创建一个全局变量(造成代码污染,成为全局object的一个属性)。声明变量和非声明变量的区别是:
- 声明变量的作用域限制在其声明位置的上下文中,而非声明变量总是全局的。
- 声明变量在任何代码执行前创建,而非声明变量只有在执行赋值操作的时候才会被创建。
声明变量是它所在上下文环境的不可配置属性(configurable: false),非声明变量在全局域中是可配置的(例如非声明变量可以用 delete 删除)。
提倡必须使用声明变量!!!(无论是否在函数内)
- 变量提升:由于变量声明(以及其他声明)总是在任意代码执行之前处理的,所以在代码中的任意位置声明变量总是等效于在代码开头声明。这意味着变量可以在声明之前使用。这是 var 与 let 声明之间最大的不同。如下图:
let
let 声明了一个块级域的局部变量,并且可以给它一个初始化值。
let 把变量的作用域限制在块级域中。
let 声明的变量作用域包含定义它的块以及任何包含的子块中。这点与 var 相似。
在同一个函数或同一个作用域中用 let 重复定义一个变量将引起 TypeError 。
let 提供了一种在块的范围内获取变量的值,而不会影响块外面名字相同的变量的值的方法。
let 不存在变量提升。
const
const 声明创建一个只读的常量。这不意味着常量指向的值不可变,而是变量标识符的值只能赋值一次。(注意区分常量的值和常量指向的值的不同)
注:这点与Java C++中类似。即:指向常量的指针,表示这个指针不能改变所指向变量的值,仅表示“只读”。但是被指向的变量的值可以通过其他手段改变。可以在全局作用域或者函数内声明常量,声明后必须同时赋值。对于const来说,只声明不赋值,就会报错。
常量拥有块作用域,和使用 let 定义的变量十分相似。常量的值不能通过再赋值改变,也不能再次声明。
一个常量不能和它所在相同作用域内的其他变量或函数拥有相同的名称。
常量可以是一个具体的值,也可以是一个对象。注意:常量是对象时,对象内部的属性可变而不受保护。例如:
123const myObject = {"key":"value"};myObject = {"newKey":"newValue"}; // 报错,常量不能再次赋值改变myObject.key = "newValue"; // 成功,可修改对象常量的属性