变量声明
JavaScript中有3种方式声明变量:var
let
const
变量提升是JavaScript的一种机制:在执行代码之前,变量和函数声明会移至其作用域的顶部
var a = 1;
var b = 2;
js解析这个代码时,它实际上是按照如下方式解析的
var a;
var b;
a = 1;
b = 2;
也就是js会先把所有变量都声明好了之后,然后才进行赋值,并不是声明一个变量就赋值
下面这段代码v1部分,实际上是按照v2的方式解析的,所以输出的是1、undefined
function v1() {
var a = 1;
console.log(a);
console.log(b);
var b = 2;
}
function v2() {
var a;
var b;
a = 1;
console.log(a);
console.log(b);
b = 2;
}
在作用域中,不管变量和函数写在什么位置,所有变量会被整体提升到作用域顶部,所有函数也会被整体提升到作用域顶部,但是函数整体在变量整体的后面
下面这段代码v1部分,实际上是按照v2的方式解析的,所以输出的是a()、1、1
function v1() {
console.log(a);
var a = 1;
console.log(a);
function a() {}
console.log(a)
}
function v2() {
var a;
function a() {}
console.log(a);
a = 1;
console.log(a);
console.log(a);
}
var
可以在全局范围声明或函数局部范围内声明,可以重新声明和修改
当在全局范围声明var变量时,作用域是全局的。这意味着在全局范围用var声明的任何变量都可以在windows中使用
当在函数中声明var时,作用域是局部的。这意味着它只能在函数内访问
用var声明的变量会被提升到其作用域的顶部,并使用undefined对其进行初始化
let
块级作用域,是由{}界定的代码块,可以被修改但是不能被重新声明
用let声明的变量会被提升到其作用域的顶部,不会对值进行初始化
const
用const声明的变量保持常量值,作用域和let一样,是块级作用域
const不能被修改并且不能被重新声明
但是,当用const声明对象时,这种行为却有所不同。虽然不能更新const对象,但是可以更新该对象的属性
和let一样,const声明也被提升到其作用域的顶部,但是没有初始化
循环中的作用域
可以理解为在for的{}代码块,let每次都是一个局部变量,而var是一个公用的全局变量
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
// 输出结果
10 10 10 10 10 10 10 10 10 10
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log(i);
}, 0);
}
// 输出结果
0 1 2 3 4 5 6 7 8 9