知识梳理---js执行机制

244 阅读3分钟

关于js的执行时的梳理

在js的执行期间,包含了许多我们看不到的步骤,这些步骤可以更好的让我们去知晓我们定义的变量的可访问情况,以下是一些相关的知识梳理

预编译阶段 💻

预编译阶段会将一些函数变量声明进行提升,以下是es5中的两种函数申明方式的区别

var

js在预编译阶段,以var形式声明的变量会在内存空间中为变量开辟一个新的内存空间,指向这个变量名,同时将新创建的变量赋值为undefined,执行阶段才会赋值

function

用函数申明的形式创建的函数会在内存中开辟内存空间,并对函数执行创建的工作,在这个阶段作用域已经定义

引擎运行执行阶段

一、执行上下文创建阶段 在函数的创建阶段中,经历以下几步操作

  • 1 生成变量对象

  • 2 建立作用域链

  • 3 确定this指向

1 生成变量对象

  在执行上下文的创建阶段,变量对象会储存着
  函数所有的形参   ----赋值为undefined
  所有的函数声明    ---在内存空间中开辟空间
  所有的变量声明    ---赋值为undefined---如果与函数或者形参名相同,也不会干扰到

2 建立作用域链

在此时作用域链将被创建,函数在当前作用域下RHS引用没有访问到变量的话,可以通过作用域链逐级向上访问变量

3 确立this的指向

 在这一阶段,this的指向会得到确立
 this的指向时在调用时期确立的,而不是在函数定义时期确立的    

总结:

this
主要与调用该函数的对象相关联,影响到了该对象中的数据是否可以通过this访问,主要关联的是调用该函数的对象数据

作用域 
主要与函数的定义相关联,影响到了函数中定义的变量的可见性,也就是说主要关联着我们函数定义的变量数据

二、执行上下文的执行阶段

  • 1 对之前创建的变量进行赋值

  • 2 对函数进行引用

  • 3 执行其他的代码

     在这个时期,之前创建阶段所定义的形参函数声明等都会得到赋值,同时内部定义的代码也会得到执行
     在此时,变量对象也会转换为书上所说的活动对象
    

拓展知识:

关于作用域与作用域链建立时期的区分:

   在创建阶段下定义的函数作用域已经确立 
   作用域链是在函数执行的期,执行上下文创建阶段确立的

可变对象: 所有压入函数作用域链的值,都是对可变对象的引用,当所有对这个可变对象的引用都断开的时候, 这个可变对象才能被垃圾回收

关于作用域创建阶段和运行时阶段

一、创建时阶段

当浏览器窗口打开的时候,就会自动开启一个最顶级的运行时阶段的作用域 一般称之为全局作用域,在这个作用域中定义出来的函数会自动进入创建时阶段,拥有自己的作用域 创建时阶段会创建自己运行时阶段的可变对象引用,逐级插入作用域链中,直到最后一个顶级的global对象

二、运行时阶段

运行时阶段是指函数通过()运行的时候,会创建一个运行期上下文对象,拥有自己的[[scope]]属性,然后推入作用域链中