关于var、let和const
三个关键字都是用来定义变量的。
作用域
var:使用var定义的变量会成为包含它的函数的局部变量,即作用域为函数内。
let:使用let定义的变量的作用域为块内。
const:作用域与let相同,也是块内作用域。
var name = 'wzx';
console.log(name); // wzx
if(true){
var name = 'lll';
console.log(name); // lll
}
console.log(name); // lll
let age = 11;
console.log(age); //11
if(true){
let age = 12;
console.log(age); //12
}
console.log(age); //11
let在全局作用域中声明的变量不会成为window对象的属性值,但var会。
变量声明提升
var 支持变量声明提升:
function foo(){
console.log(age); //undefined
var age = 26;
}
foo();
变量声明提升后,变量声明会自动提升到函数作用域的顶部。
let 不支持变量申明提升,将let声明的变量提升会报错,这时发生暂时性死区。
//变量不提升
console.log(age); //ReferenceError: age没有被定义
let age = 23;
const也不支持变量声明提升,因为const声明的变量,声明时就被初始化。变量值不可变。类似常量。但是变量如果是引用对象,变量的属性可以变。
冗余声明
let不允许同一个块作用域中出现冗余申明;
for循环中的var、let和const
在for循环中,用var修饰的迭代变量会渗透到循环体外;
for(var i; i < 10; i++){
console.log(i);
}
console.log(i) //10
用let修饰的迭代变量的作用域仅限于循环块中;
for(let i; i < 10; i++){
console.log(i);
}
console.log(i); //ReferenceError: i没有定义
const不会用来修饰迭代变量,因为它不能改变,所以const声明的变量通常为连续输出的同一个值。在 for-of 和 for-in 中会被用到;
let i=0;
for (const n=10; i<5; i++ ){
console.log(n);
}
//10、10、10、10、10
for(const key in {a: 1, b: 2});{
console.log(key);
}
//a、b
for(const value of [1,2,3,4,5,6]){
console.log(value);
}
//1、2、3、4、5、6
注意 :在for循环中使用延时器时,使用var声明迭代变量,迭代变量的保存值为导致循环退出的值,用let声明的迭代变量,js引擎会在每次循环中声明一个新变量。
for(var i = 0; i<5; i++){
setTimeout(function(){
console.log(i);
},0)
}
//输出为:5,5,5,5,5
for(let i = 0; i<5; i++){
setTimeout(function(){
console.log(i);
},0)
}
//输出为:1,2,3,4,5
最佳实践
1.尽量不用var
2.const优先,let次之。