变量提升

41 阅读2分钟

变量提升小结

概念:变量提升是javascript 代码在执行过程中,javascript 引擎会把将带有var, function关键字的变量提升到代码的最前面的行为。

  • 变量提升只是变量声明部分提升

  • 函数提升是函数整体提升

  • 变量提升发生在编译环节,而赋值操作发生在执行阶段

  • 函数声明提升会优先于变量声明提升(导致变量声明被覆盖)(若是还有函数名相同的函数需要提升,则会覆盖之前提升的函数声明)

  • 用let声明的变量不存在变量提升现象

  • 全局作用域中,不管带不带var都是给window添加属性

例子一:

fn(); 
function fn() { console.log(1); }  
fn(); 
function fn() { console.log(2); }
fn(); 
var fn = function () { console.log(3); }  
fn(); 
function fn() { console.log(4); }
fn(); 
function fn() { console.log(5); }
fn(); 

5
5
5
3
3
3
// 1. 函数声明提升(按顺序覆盖,最后一个生效) 
function fn() { console.log(5); } 

// 2. 变量声明提升(但赋值不提升) 
var fn; // 注意:此声明被函数声明覆盖,无效 

// 3. 执行阶段 
fn(); // 输出 5(调用已提升的函数) 
fn(); // 输出 5(仍调用同一个函数) 
fn(); // 输出 5(仍调用同一个函数) 

fn = function () { console.log(3); }; // 变量赋值,覆盖函数 
fn(); // 输出 3(调用赋值后的函数) 

// 后续的函数声明不会生效(已进入执行阶段) 
fn(); // 输出 3(仍调用赋值后的函数) 
fn(); // 输出 3(仍调用赋值后的函数)

例子二:

var foo = 1;
function bar() {
	if (!foo) {
		var foo = 10;
	}
	console.log(foo);
}
bar();

10
var foo = 1; 
function bar() { 
    // 变量提升:函数内的 var foo 被提升到函数顶部 
    var foo; 
    // 声明被提升,但赋值保留在原处 
    if (!foo) { 
        // 此时 foo 为 undefined,!undefined 为 true 
        foo = 10; 
        // 赋值操作 
    } 
    console.log(foo); // 输出 10 
} 
bar();