js之执行环境

311 阅读2分钟

为什么需要函数提升?

这是为了解决两个循环调用的情况(函数A调用函数B,如果没有函数提升,就会始终有一个还没有声明,就会报错)

js函数提升是怎么做到的?

归功于执行上下文! 执行上下文又称执行环境(本文统一使用执行环境)

那么什么是执行环境?

执行环境定义了变量或者函数有权访问的其他数据,决定了他们各自的行为。每当JavaScript代码在运行的时候,它都是在执行环境中运行。

一个执行环境定义了函数执行时的环境。函数每次执行时对应的执行环境都是独一无二的,因此多次调用同一个函数会导致创建多个执行环境。当函数执行完毕,执行环境就被销毁。

执行环境的分类?

执行环境分为:

  1. 函数执行环境
  2. 全局执行环境 ->是最外围的一个执行环境,在web浏览器中,全局执行环境是window对象。因此所有全局变量和函数都是作为window的属性和函数创建的。
  3. Eval 函数执行环境(最后一个不经常用,所以这里不讨论)

执行环境、变量对象(variable object)、活动对象(activation object)的关系?

  • 每个执行环境都有一个与之关联的变量对象(VO)
  • 变量对象(VO)保存的是这个环境中定义的所有的变量和函数。
  • 当这个环境是函数时候,其活动对象(AO)就是变量对象。
  • 一个函数的活动对象(AO)包含:局部变量、arguments、this。

执行环境的创建阶段?

当执行一个函数的时候,会首选创建该函数的执行环境,然后再一行一行执行。

创建执行环境: 也就是给执行环境创建一个作用域链——>这个作用域链的最前端,是当前执行代码所在环境的变量对象,当这个环境是函数时候,变量对象也就是活动对象。

这个作用域链的第二个变量对象,来自包含环境(外部一层),就这样依次顺延,直至延续要全局执行环境

也就是说全局执行环境始终是作用域链中最后一个变量对象。

执行环境创建好后,就开始一行一行执行代码了,执行完之后,会将该执行环境出栈。

所以函数提升,或者变量提升,是因为在执行时候,已经创建好了执行环境(执行环境里面包含作用域链,因此作用域链也创建好了),只是在运行的时候,再进行赋值操作。 所以有函数提升,和变量提升:

console.log(a)
var a = 1
console.log(b)
function b(){
	console.log('b')
}
打印结果:
// undefined
// ƒ b(){
	console.log('b')
}