持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情
铃铛说点题外话
上一篇我们详细说了变量提升和函数提升,这一篇我们就根据几个案例详细的说说函数的执行过程
铃铛说正文
var message = "hello global"
function foo(){
console.log(message)
}
function bar(){
var message = "hello bar"
foo()
}
bar()
上面这段代码的输出结果是:hello global。接下来我们详细说说这个函数的执行过程
- 第一步会创建一个全局作用域下的变量
message为hello global - 创建一个
ECStrack(调用栈),这里面存在一个foo函数执行上下文,函数会开辟一块新的内存地址存放函数的信息:执行console.log(message) - 继续开辟新的内存地址存放
bar函数的信息,这里面存放着执行信息foo调用了foo函数 - 最后调用
bar函数
输出结果:所以这里首先会调用函数bar,在函数bar里定义message变量的值为hello bar,之后调用函数foo,这里函数foo只有一个输出语句,输出变量message的值。这里需要注意,函数foo函数里面输出的值。这里需要注意函数foo里的输出语句实际是在要函数foo函数作用域内查找,如果自身查找不到会去上一级父级作用域进行查找。这里函数foo中并没有变量message所以回去函数foo的父级查找是否存在该变量,这里也就是全局的hello global,所以最终结果为hello global。
这里可能也会有一部分同学不明白函数foo是怎么查找到父级作用域的变量的,其实很简单,这里涉及到一个新的知识点:作用域和作用域链。实际上父子作用域之间是通过一条作用域链连接在一起的,让我们能查找到父级的变量。
跟铃铛说再见
这里也留下了一个谜题:作用域和作用域链,我放在下一篇详细说说作用域和作用域链