变量提升小结
概念:变量提升是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();