1. 变量声明提升
· 通过var定义的变量,在定义语句之前就可以访问到;变量的声明会提升到函数的顶部,变量的赋值并不会
· 值:undefined
function fn( ) {
console.log(a);
var a = 1;
}
fn(); // undefined
相当于
function fn( ) {
var a;
console.log(a);
a = 1;
}
fn();
2. 函数声明提升
· 通过function声明的函数,在之前就可以调用;函数表达式不会进行变量提升,只有函数声明形式才可以
· 值:函数定义(对象)
// 函数声明式
foo() ;
function foo () {
console.log(' hello ') ; // 正常输出hello
}
// 函数表达式 (不会进行函数提升,可以结合变量提升来理解
foo2();
var foo2 = function() {
console.log(' hello ')
}; // 报错:foo2 is not a function
相当于
var foo2;
foo2();
foo2 = function() {
console.log(' hello ')
};
3. 先看一下作用域的一些东西:
// 全局作用域和函数作用域
var a = ‘global’;
function foo () {
var b = ' lobal ';
console.log(a); // global 可以访问到全局变量global
console.log(b); // lobal 可以访问到局部(函数作用域)变量lobal
}
foo();
// 块级作用域
{
let c = ‘ block’
console.log(c); // block
}
console.log(c); // 脱离块级作用域 报错:c is not defined
4. 变量提升和函数提升同时存在
var a = true;
foo();
function foo() {
if (a) {
var a = 10;
}
console.log(a); // undefined
}
// 相当于
var a = true;
foo();
function foo () {
var a;
if (a) {
a = 10;
}
}
5. 变量提升和函数提升的优先级
console.log(a);
console.log(a());
var a = 1;
function a() {
console.log(2);
}
a = 3;
console.log(a);
console.log(a());
// 相当于
function a() { // 先函数提升
console.log(2);
}
var a; // 再变量提升
console.log(a); // function a
console.log(a()); // 2
a = 1;
a = 3;
console.log(a); // 3
console.log(a()); // a此时已经指向了3,不再是一个函数,执行时报错
5. 变量提升和函数提升的一些例子
console.log(bar); // f bar() { console.log(123) }
console.log(bar()); // undefined
var bar = 456;
function bar() {
console.log(123); // 123
}
console.log(bar); // 456
bar = 789;
console.log(bar); // 789
console.log(bar()) // bar is not a function
相当于:
// js执行步骤
// 函数提升,函数提升优先级高于变量提升
var bar = function() {
console.log(123)
};
// 变量提升,变量提升不会覆盖(同名)函数提升,只有变量再次赋值时,才会被覆盖
var bar;
console.log(bar);
console.log(bar());
// 变量赋值,覆盖同名函数字面量
bar = 456;
console.log(bar);
// 再次赋值
bar = 789
console.log(bar);
console.log(bar());
总之,牢记三点:
只有声明本身会被提升,而赋值操作不会被提升。
变量会提升到其所在函数的最上面,而不是整个程序的最上面。
函数声明会被提升,但函数表达式不会被提升。