题目⑤ 说一下js的执行流程

栗子

print() // 1
console.log(str) // 2
var str = 'hello' // 3
function print() {
  // 4
  console.log(str)
}
// output: undefined undefined

1. 变量提升

  • js在执行的过程中,js引擎把变量和函数的声明部分提升到代码开头的行为。

2. js执行流程

变量和函数声明在代码里的位置是不会改变的,而且在编译阶段被js引擎放入内存中,js代码编译完才会进入执行阶段

  • 流程:一段js代码 -> 编译阶段 -> 执行阶段

js执行流程.png

  • 由图可见:js代码编译后会生成两部分内容:执行上下文和可执行代码

执行上下文

执行上下文:js执行一段代码时的运行环境

执行上下文中存在一个变量环境的对象

  • 变量环境:该对象保存了变量提升的内容

2.1 编译阶段

  • 1和2 不是声明操作,js引擎不做任何处理

  • 3通过var声明变量,js引擎在环境变量中创建名为str的属性,并初始化为undefined

  • 4是一个函数声明,js引擎会将函数定义部分存在堆heap中,并在环境变量中创建名为print的属性,并将print的值指向堆中函数的位置

Variable Environment:
str -> undefined,
print -> function() { console.log(str)}

js引擎会把声明之外的代码编译成可执行代码

print() // 1
console.log(str) // 2
str = 'hello' // 3

2.2 执行阶段

  • 执行1时,js引擎开始在变量环境中寻找该函数

    • 变量环境中print存在该函数的引用,所以js引擎便开始执行该函数

    • 在执行过程中发现函数用了str变量,js引擎在变量环境中寻找str变量

    • 此时str在环境变量中值为undefined,输出undefined

  • 执行2时,js引擎在变量环境中查找str,此时str在变量环境中的值为undefined,输出undefined

  • 3是一个赋值操作,把‘hello’赋值给str,赋值结束后变量环境改变

Variable Environment:
str -> 'hello',
print -> function() { console.log(str)}

3. 代码中存在多个相同变量和函数时怎么办

3.1 栗子

a() // 1
var a = 'hello, world' // 2
console.log(a) // 3
function a() {
  // 4
  console.log('inner a function 1')
}
var a = 'hello, tomorrow' // 5
console.log(a) // 6
function a() {
  // 7
  console.log('inner a function 2')
}
a() // 8
  • 执行结果
// inner a function 2
// hello, world
// hello, tomorrow
// 报错 a is not a function

3.2 编译阶段

  • 1函数调用不做处理

  • 2有var声明变量,在变量环境中创建a变量并初始化为undefined

  • 3函数调用不做处理

  • 4js引擎发现有同名function定义的函数a,将函数定义存储到堆heap中,并在变量环境中查找是否存在a,存在则把a的值指向该函数在堆中的位置

  • 5有var声明,在变量环境在查找是否存在a,存在并且a有值,不做处理

  • 6函数调用不做处理

  • 7js引擎发现存在同名funtion定义的函数a,把函数定义存储在堆中,并在变量环境中查找是否存在a属性,存在则把a的值指向该函数在堆中的位置

Variable Environent:
  a -> function() { console.log('inner a function 2') }

3.3 执行阶段

a() // 1
a = 'hello, world' // 2
console.log(a) // 3
a = 'hello, tomorrow' // 4
console.log(a) // 5
a() // 6
  • 1js引擎开始在变量环境中寻找该函数

    • 变量环境中a存在该函数的引用,所以js引擎便开始执行该函数

    • 输出inner a funciton 2

  • 2赋值操作,把‘hello,world'赋值给a,变量环境对象改变

    • 变量环境:a -> 'hello, world'
  • 3打印a的信息

    • 输出hello, world
  • 4赋值操作,把’hello,tomorrow‘赋值给a,变量环境对象该百年

    • 变量环境:a -> 'hello, tomorrow'
  • 5函数调用,但在变量环境中,a的值为'hello, tomorrow',并没有指向函数的位置,所以报错

posted on 2021-09-14 17:24  pleaseAnswer  阅读(149)  评论(0编辑  收藏  举报