块作用域{ }
在ES6之前,JS的作用域只有两种,全局作用域和函数作用域,没有块作用域的概念。ES6中增加了块级作用域,由{ }包括,if语句和for语句里面的{ }也属于块作用域。
var、let、const
1、var声明的变量会挂载在window上,而let和const声明的变量不会:
var a = 1;
let b = 2;
const c = 3;
console.log(a, window.a); // 1 1
console.log(b, window.b); // 2 undefined
console.log(c, window.c); // 3 undefined
2、var声明的变量存在变量提升,let和const不存在变量提升
console.log(a); // undefined
console.log(c); // undefined
console.log(d); // function d() {}
console.log(b); // 报错, b is not defined
var a = 0;
let b = 1;
var c = function () {
};
function d() {
}
let声明的变量不会提升,函数声明会完全提升,上面的代码与下面的等价:
var a;
var c;
function d() {
}
console.log(a);
console.log(c);
console.log(d);
console.log(b);
a = 0;
let b = 1;
c = function() {
};
3、let和const声明形成块作用域
if(1) {
var a = 1;
let b = 2;
const c = 3;
}
console.log(a); // 1
console.log(b); // 报错,b is not defined
console.log(c); // 报错,c is not defined
4、同一作用域下的let和const不能声明同名变量,var可以
var a = 1;
console.log(a); // 1
var a = 2;
console.log(a); // 2
let a = 1;
let a = 2;
// Uncaught SyntaxError: Identifier 'a' has already been declared
5、暂存死区
var a = 1;
if(1) {
a = 2;
let a = 3;
}
// 在当前作用域中存在a使用let/const声明的情况下,给a赋值10,只会在当前作用域找变量a;而这时还未声明,所以就会报错,a is not defined
6、const
const a = 1;
const list = [];
list[0] = 2;
console.log(list); // [2]
const obj = {
a: 1
};
obj.name = 'lili';
obj.a = 2;
console.log(obj); // {a:2, name: 'lili'}
一旦声明必须赋值,不能用null占位;
声明后不能再修改;
如果声明的是复合类型数据,可以修改其属性