你不知道的变量提升和预编译

163 阅读2分钟

前言:代码是怎么运行的

  1. 在执行过程中,若使用未声明的变量,js执行会报错
  2. 在一个变量定义之前使用它,不会报错,但是该变量的值为undefined,而不是定义的值
  3. 在一个函数定义之前使用它,是不会报错的,且函数能正确执行 这些都是js引擎的按照规则执行的结果,那么引擎是按照什么规则来执行的呢?

变量提升

javaScript 代码在执行过程中,javaScript引擎会把变量声明部分和函数声明部分提升到代码的最前面的“行为”,这就是变量提示。 怎么说呢,我们已一个小dom为例:

function getName(){
  var myname='小明'
  console.log(myname);
}
var name='小红'
console.log(name);

js引擎在代码执行之前会进行预编译(后面会讲解),在预编译的时候会变量提升,所以经过变量提示之后代码是下面这样的:

Go:{
  getName:Function
  name:undefined
}

然后再从上至下执行代码,所以这就是为什么在一个变量定义之前使用它,不会报错,但是该变量的值为undefined,而不是定义的值。

预编译

预编译分为全局预编译和函数预编译,并且预编译发生在代码执行的前一刻,如下:

函数预编译(四部曲):

  1. 创建AO对象(Activation Object)(执行上下文对象)
  2. 找形参和变量声明,将变量声明和形参作为AO的属性名,值为undefined
  3. 将实参和形参值统一
  4. 在函数体里找函数声明,将函数名作为AO对象的属性名,值赋予函数体

全局预编译(三部曲):

  1. 创建GO对象
  2. 找形参和变量声明,将变量声明和形参作为GO的属性名,值为undefined
  3. 在全局里找函数声明,将函数名作为GO对象的属性名,值赋予函数体