首先想知道三者的区别,需要要对ECMAscript有一定了解。
ECMAscript5.0中有 全局作用域和函数作用域,却没有块级作用域,于是es6中就引进了 let和const弥补了es5的不足。
let
:
- 块级作用域
- 暂时性死区
- 变量不允许多次声明
- 不存在变量提升
/*for循环,for循环里面是父级作用域,循环体内是另一个*/
for( let i = 0 ; i < 3 ; i++ ){
let i = 'abc' //用var替代let会报错提示已经定义,若没有任何关键字则每次赋值给i,最后只会输出一次abc
console.log(i) // 输出3次abc
}
function varTest() {
var x = 31;
if (true) {
var x = 71; // same variable!
console.log(x); // 71
}
console.log(x); // 71
}
function letTest() {
let x = 31;
if (true) {
let x = 71; // different variable
console.log(x); // 71
}
console.log(x); // 31
}
块级作用域:即其在整个大括号 {} 之内可见。如果使用 let 来重写上面的 for 循环的话,会报错。
/*1.var变量*/
console.log(a); //undefined
var a=1;
b=10;
console.log(b); //10
var b;
/*2.let变量*/
console.log(c); // Uncaught ReferenceError: c is not defined
let c=2;
console.log(d); // Uncaught ReferenceError: d is not defined
let d;
暂时性死区: let 和 var 的第二点不同是,在变量声明之前就访问变量的话,会直接提示 ReferenceError,而不像 var 那样使用默认值 undefined.
var x = 5; // 初始化 x
elem = document.getElementById("demo"); // 查找元素
elem.innerHTML = "x 为:" + x + ",y 为:" + y; // 显示 x 和 y
var y = 7; // 初始化 y
</script>
结果输出: x 为:5,y 为:undefined
y 输出了 undefined,这是因为变量声明 (var y) 提升了,但是初始化(y = 7) 并不会提升,所以 y 变量是一个未定义的变量。
<script>
a=5;
show();
var a;
function show(){};
预解析:
function show(){};
var a;
a=5;
show(); //需要注意都是函数声明提升直接把整个函数提到执行环境的最顶端。
变量提升: var 存在变量提升,而 let,const(后面会提及)声明的变量却不存在变量提升,所以用 let 定义的变量一定要在声明后再使用,否则会报错。
<script>
if (true) {
let a;
let a; // Uncaught SyntaxError: Identifier 'a' has already been declared
}
if(true){
var d;
var d; //不会报错
}
if (true) {
var c;
let c; // Uncaught SyntaxError: Identifier 'c' has already been declared
}
if (true) {
let d;
var d; // Uncaught SyntaxError: Identifier 'd' has already been declared
}
</script>
变量多次声明: let命令不允许变量多次声明。否则报错。
另外let 和var有着全局属性和全局变量上的区别:
ES5中全局对象的属性与全局变量基本是等价的,但是也有区别,比如通过var声明的全局变量不能使用delete从 window/global ( global是针对与node环境)上删除,不过在变量的访问上基本等价。
ES6 中做了严格的区分,使用 var 和 function 声明的全局变量依旧作为全局对象的属性,使用 let, const 命令声明的全局变量不属于全局对象的属性。
var a = 10;
console.log(window.a); //10
console.log(this.a) //10
let b = 20;
console.log(window.b); // undefined
console.log(this.b) // undefined
const
与let有些地方类似,但又不同。
const 变量一旦被赋值,就不能再改变了,但是这并不意味着使用 const 声明的变量本身不可变,只是说它不可被再次赋值了,而且const 声明的变量必须经过初始化。
1、一旦声明必须赋值,不能用null占位
2、声明的变量是只读的
3、如果是复杂类型的数据,可以修改其属性
const a = 100;
a = 2; // // Uncaught TypeError: Assignment to constant variable
const b; // Uncaught SyntaxError: Missing initializer in const declaration
const list = [];
list[0] = 10;
console.log(list); // [10]
const obj = {a:100};
obj.name = 'apple';
obj.a = 10000;
console.log(obj); // {a:10000,name:'apple'}