1. 变量提升的概念
变量提升简单来说就是把我们所写的类似于var a = 123;这样的代码,声明提升到它所在作用域的顶端去执行,到我们代码所在的位置来赋值。
2. 变量的提升
使用var 声明的变量会被提前到所有代码执行之前
console.log(x)
var x = 123;
上面的代码执行顺序应该是这样
var x;
console.log(x);
x = 123;
// 因此打印的内容是undefined,因为x声明了, 但是没有赋值
3. 函数的提升
使用函数声明创建的函数会被提前到所有代码执行之前
但是通过构造方法和表达式方式创建的函数不会被提前
console.log(fun);
fun();
var fun = function(){
console.log("fun");
}
运行结果:
undefined
Uncaught TypeError : fun is not a function
解释:
通过var 声明的变量fun会被提前到所有代码执行之前, 所以在第一行打印fun会打印undefined, 第二行执行fun函数, 由于fun是undefined, 因此报错undefined不是个函数
通过变量声明创建的函数则不会出现这个问题
console.log(fun);
fun();
function fun(){
console.log(1);
}
运行结果:
f fun() {
console.log(1);
}
1
解释:
由于通过函数声明创建函数, 因此函数被提前, 因此可以直接调用而不会出错
4. 变量提升的Demo
console.log(v1);
var v1 = 100;
function foo() {
console.log(v1);
var v1 = 200;
console.log(v1);
}
foo();
console.log(v1);
// 运行结果:
// undefined
// undefined
// 200
// 100
解释:
作对这道题其实不难, 重要的是理解变量提升的概念,提升到当前作用域的最顶端
浏览器的解析顺序应该是这样
var v1;
console.log(v1); //undefined
v1 = 100;
function foo(){
var vl; // 函数作用域中v1于覆盖了全局作用域的v1
console.log(vl); //undefined
v1 = 200;
console.log(v1); // 200
}
foo();
console.log(v1); // 100(第三行赋值过,因此是100)
5. 函数提升的Demo
foo();
var foo;
function foo () {
console.log(1);
}
foo = function () {
console.log(2);
}
// 运行结果: 1
浏览器的编译过程应该是这样
function foo(){
console.log(1);
}
var foo;
foo();
foo = function(){
console.log(2);
}
因此输出结果应该是1, 如果在最后一行在调用一遍foo(), 则会再次输出2