题目:说一下js的执行流程
题解
栗子
print() // 1
console.log(str) // 2
var str = 'hello' // 3
function print() {
// 4
console.log(str)
}
// output: undefined undefined
变量提升
- js在执行的过程中,js引擎把变量和函数的声明部分提升到代码开头的行为。
js执行流程
变量和函数声明在代码里的位置是不会改变的,而且在编译阶段被js引擎放入内存中,js代码编译完才会进入执行阶段
- 流程:一段js代码 -> 编译阶段 -> 执行阶段
- 由图可见:js代码编译后会生成两部分内容:执行上下文和可执行代码
执行上下文
执行上下文:js执行一段代码时的运行环境 执行上下文中存在一个变量环境的对象
- 变量环境:该对象保存了变量提升的内容
编译阶段
- 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
执行阶段
- 执行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)}
代码中存在多个相同变量和函数时怎么办
栗子
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
编译阶段
- 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') }
执行阶段
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',并没有指向函数的位置,所以报错