JavaScript中的var、let、const的差别

学了很久的js,却一直没怎么在意var和let区别,这里记录下

1
2
3
var a = 1;  
//这里的var是声明关键字,a是变量标识 ,=是赋值符号,1是值
console.log(a); ///1

var 预编译阶段

这里首先声明(declaration)了一个名为a的变量,再对其初始化(initialization),赋值为undefined

所以如果在声明变量之前,就引用了变量,就会得到undefined,这里存在一个提升的问题

1
2
console.log(a);  //undefined
var a = 1;

如果不声明变量就直接引用将得到报错

1
console.log(a);  ///Uncaught ReferenceError: Cannot access 'a' before initialization

所以存在var声明的变量有一个提升的过程 执行顺序和变量的访问有冲突 声明之前就可以引用

故此,ES6有了let语法

1
2
console.log(two);  //Uncaught ReferenceError: Cannot access 'two' before initialization
let two = "123"

let预编译阶段

这里首先声明了一个叫two的变量,却没有对其初始化,故有了以上报错

1
2
let two;
console.log(two); //undefined

这里undefined是在执行期的时候,js系统默认赋值undefined,undefined是js的唯一默认值

再者,var是用来声明全局变量或者函数作用域内的局部变量,而let用于声明块级作用域的局部变量。

var 声明的变量 如果写在最表层就是全局变量,是全局作用域,特别是引用多个js文件的情况,可能会出现变量名冲突

但是如果js代码是以模块的形式引入这不会注册全局作用域

1
<script type="module" src="js_test.js"></script>

其本质类似于立即执行函数

1
2
3
4
5
6
; (
function () {
var one = "123"
console.log(one);
}
)();

若是使用let声明变量,则其变量的作用域是变量所在代码块(函数块、if、for等块)内部,也就是说该变量仅在代码块内有效,其不会产生全局变量,这称之为块级作用域。

1
2
3
4
5
6
let a = "one"
console.log(a); //one
for (let a = 0; a < 1; a++) {
console.log(a); //0
}
console.log(a); //one

const 与let类似,但是存在不同

cosnt 声明的变量必须进行赋值,且赋值后不可改变,故此可以认为其是常量。const 声明的变量也具有块级作用域,与let相同。

1
2
const a = { one: 1 }
console.log(a); //{one:1}
1
2
3
const a = { one: 1 }
a = { "two": 2 } //不可以给常量变量赋值
console.log(a); //Uncaught TypeError: Assignment to constant variable.

但是,可以通过修改const常量的属性重新赋值,来修改a的内容

1
2
3
4
5
6
const a = { one: 1 }
function getNun() {
a.one = 0;
};
getNun()
console.log(a); //{one: 0}

所以const声明的变量也不意味着其所声明的变量是完全不可变的