var关键字和变量提升
javascript 的变量是松散类型的,意思是可用于保存任何数据类型,每个变量只不过是一个用于保存任意值的命名占位符。
var关键字声明的是函数作用域
var声明提升:
function fn() {
console.log(name);
var name = 12;
}
fn();//undefined
相当于:
function fn() {
var name;
console.log(name);
name = 12;
}
fn();//undefined
因此不会报错,而是输出undefined
let声明
let声明的是块级作用域,块级作用域是函数作用域的子集,因此适用于var的作用域限制同样也适用于let.
let不允许同一个块级作用域中出现冗余声明,对声明冗余不会因为let和var混用而受影响。
if (true) {
let age;
let age;
console.log(age);
}
console.log(age);
报错:Uncaught SyntaxError: Identifier 'age' has already been declared(age已经声明过了)
let出现的暂时性死区
let声明不会变量提升,在let变量声明之前不能以任何方式来引用为声明的变量。在let声明之前的执行瞬间被称为“暂时性死区”,都会抛出ReferenceError。
let在全局作用域中声明的变量不会成为windows的属性,而var声明则会成为window的属性。
for循环声明
var 声明的变量会渗透到for循环外部
for (var index = 0; index < 5; index++) {
}
console.log(index);//5
let声明的变量不会渗透到for循环外部
for (let index = 0; index < 5; index++) {
}
console.log(index);//index is not defined
在适用var声明变量时,对迭代变量的奇特声明和修改:
for (var index = 0; index < 5; index++) {
setTimeout(function() {
console.log(index);//输出5个5
}, 1);
}
原因:是因为在推出循环时保存的是导致循环退出的值。改用let就不会有问题了。
const声明
1.const声明也是块级作用域
2.声明是必须赋值,后面不能再修改,相当于创建常量。
3.同let一样,不能重复声明。