const:
块级作用域,定义常量,使用的时候必须初始化。只能在块级作用域访问,不能修改,但是const定义的对象属性是可以修改的。
块作用域由 { } 包括,if语句和 for语句里面的{ }也属于块作用域。
对象是引用类型 ,对象保存的是对象的指针,const保存的是对象的指针,修改对象的属性不会对对象的指针有影响。
const a=3;
{
const a = 1;
console.log(a); // 1
}
{
// a是对象,可以修改对象的属性
const a = {
name: "1",
};
console.log(a);// { name: '1' }
a.name = "2";
console.log(a);// { name: '2' }
}
console.log(a);// 3
let:
(1)块级作用域,ES6推荐使用let定义变量,而非var。
(2)let声明的变量在相同的作用域不能重复声明。let声明的变量在不同作用域或者不同块级作用域中是可以重新声明赋值的。
(3)没有变量提升。
(4)在循环中最好是使用let声明变量,而不是使用var声明变量。
使用let和const声明的变量会出现 " 暂时性死区 " (TDZ)。
ES6明确规定:如果区块中存在let和const命令,那么这个区块对这些命令声明的变量,会形成封闭作用域,只要在声明之前就使用这些变量,就会报错。
var temp = "123";
if(true){
temp = "456";// ReferenceError
let temp;
}
if(){}块级作用域中使用let声明了一个变量,导致这个变量绑定在这个块级作用域中,所以在let声明之前,不能对let声明的变量赋值。
“ 暂时性死区 ” 会导致typeof报错。
typeof x;// ReferenceError
let x;
但是如果一个变量没有声明,使用typeof反而不会报错。
ES6规定,暂时性死区和let,const语句不出现变量提升,主要是为了减少运行时错误。
防止在变量声明前就使用这个变量,从而导致错误。
var:
(1)没有块(block)的概念,可以跨块访问, 不能跨函数访问。
(2)var声明的变量在任何地方都可以重复声明
(3)有变量提升特性
变量提升:
即编译时提前将后面声明的变量提前放入内存中,供上下文语句执行时调用;但并不是指在编译时改变语句的顺序。
无论实际声明的变量在何处,都会被设为声明在函数的顶部(如果声明不在函数中,会被视为全局作用域的顶部)
变量提升行为只会对变量进行声明操作,并不会对其进行初始化赋值。在声明变量前获取,只会得到undefined结果。
{
for (let i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);// 输出undefined
}
{
for (var i = 0; i < 5; i++) {
console.log(i);
}
console.log(i);// 5
}
全局变量,局部变量
全局变量:非函数体内(在函数体外)使用var或者let声明的变量是全局变量,拥有全局的作用域。
局部变量:在函数内使用var或者let声明的变量是局部变量,只能在函数内部使用,不能在函数外部使用。