JavaScript 变量提高

变量提高是一个将变量声明或者函数声明提高到做用域起始处的过程。在本篇博文中,咱们一块儿深刻了解这个过程的更多细节。javascript

变量的生命周期

当引擎使用变量时,它们的生命周期包含如下阶段:java

  • 声明阶段,这一阶段在做用域中注册了一个变量
  • 初始化阶段, 这一阶段分配了内存并在做用域中让内存与变量创建了一个绑定,变量会被自动初始化为 undefined
  • 赋值阶段,这一阶段为已初始化的变量分配具体的一个值

注意,声明阶段与咱们一般所说的变量声明是不一样的术语。网络

var 生命周期

网络不给力

假设这样一个场景:当解释器刚进入一个包含 var variable 的做用域时,则在任何语句执行以前,变量就已完成了声明阶段初始化阶段,且值为 undefined。语句 varibale = 'value'赋值阶段session

// 在刚进入到 func 做用域时,a 已完成了声明和初始化阶段,且值为 undefined
function func() {
  console.log(a); // undefined
  var a = 1; // 赋值阶段
  console.log(a); // 1
}
func();

function 生命周期

网络不给力

对于 function声明、初始化和赋值阶段在解释器刚进入函数做用域时,便已所有完成。函数

能够结合如下的代码,去理解 function 的变量提高过程。spa

// function 提高优先级比 var 和 let 高
foo(); // 2

// 具名函数表达式的函数名只在函数内部有效
bar(); // ReferenceError

function foo() {
  console.log(1);
}

// 多个函数声明时,后面的函数声明会覆盖以前的函数声明
function foo() {
  console.log(2);
}

// 函数声明会被提高,但函数表达式不会被提高
var foo = function bar() {
  console.log(3);
};

foo(); // 3

let 变量的生命周期

网络不给力

let 的提高是只针对声明阶段的提高。code

假设这样一个场景:当解释器刚进入一个包含 let variable 的做用域时,就已完成了声明阶段blog

从声明阶段结束到初始化阶段开始, 这段区域被称为临时死区。若是在这时访问 variable ,将会抛出 ReferenceError: variable is not defined生命周期

当解释器执行完 let variable ,变量就已完成了初始化阶段,离开了临时死区,并具备 undefined 的值。以后的语句 variable = 'value'赋值阶段ip

若是解释器遇到了 let variable = 'value' ,则完成了初始化赋值阶段。

总结

至此,总结一下变量提高过程当中的一些重要知识点:

  • var 只有声明阶段初始化阶段被提高
  • function声明阶段初始化阶段赋值阶段都被提高
  • let 只有声明阶段被提高
  • function 提高优先级比 varlet 高,且对于多个函数声明,后面的声明会覆盖前面的声明
  • 函数表达式没法被提高

参考资料

相关文章
相关标签/搜索