javascript数据类型(六)--- 函数对象之执行上下文

一、引入

1.1 变量声明提升

  通过var定义(声明)的变量, 在定义语句之前就可以访问到,其值为: undefined

var a = 3
function fn () {
    console.log(a)   //输出结果为undefined
    var a = 4  
}
fn()

 

1.2 函数声明提升

  通过function声明的函数, 在之前就可以直接调用,其值为: 函数定义(对象)

console.log(b) //undefined  变量提升
fn2() //可调用  函数提升
// fn3() //不能  变量提升

var b = 3
function fn2() {
    console.log('fn2()')
}

var fn3 = function () {
    console.log('fn3()')
}

更多关于变量提升和函数提升的知识见https://www.cnblogs.com/echolun/p/7612142.html

 

二、执行上下文

  执行上下文是一个比喻的词,用于描述运行Javascript代码的环境。JavaScript的代码按位置可简单分为全局代码和函数(局部)代码。在JavaScript中,每次运行一些Javascript代码时,引擎都会创造一个全局执行上下文,当调用函数时,在执行函数体之前,JavaScript引擎会创建一个局部的执行上下文。

2.1 全局执行上下文

  执行全局代码的过程:

  1. 在执行全局代码前将window确定为全局执行上下文
  2. 对全局数据进行预处理
    • var定义的全局变量==>undefined, 添加为window的属性
    • function声明的全局函数==>赋值(fun), 添加为window的方法
    • this==>赋值(window)
  3. 开始执行全局代码

 

2.2 函数执行上下文

  执行局部(函数)代码的过程

  1. 在调用函数, 准备执行函数体之前, 创建对应的函数执行上下文对象(虚拟的, 存在于栈中)
  2. 对局部数据进行预处理
    • 申明形参变量,并将实参变量的值赋值为形参变量,添加为执行上下文的属性
    • arguments==>赋值(实参列表), 添加为执行上下文的属性
    • var定义的局部变量==>undefined, 添加为执行上下文的属性
    • function声明的函数 ==>赋值(fun), 添加为执行上下文的方法
    • this==>赋值(调用函数的对象)
  3. 开始执行函数体代码

 

三、执行上下文栈

  在全局代码执行前, JS引擎就会创建一个栈来存储管理所有的执行上下文对象(栈结构不了解的自行查询资料)。

  • 在全局执行上下文(window)确定后, 将其添加到栈中(压栈)
  • 在函数执行上下文创建后, 将其添加到栈中(压栈)
  • 在当前函数执行完后,将栈顶的对象移除(出栈)
  • 当所有的代码执行完后, 栈中只剩下window

如下代码执行的过程中会出现的上下文栈的变化图所示:

//创建全局上下文,并将该全局上下文储存到上下文栈中
var
a = 10 var bar = function (x) { var b = 5 foo(x + b) //创建foo的局部上下文栈,并将该上下文对象存储到栈中,当函数foo执行完成后自动释放该执行上下文,跳到bar执行上下文中
} 

var foo = function (y) {
  var c = 5 console.log(a + c + y)
}
bar(
10) //创建bar的局部上下文对象,并将该上下文对象存储到栈中

试题:

查看如此代码,分析输出内容

console.log('gb: '+ i)
var i = 1
foo(1)
function foo(i) {
    if (i == 4) {
      return
    }
    console.log('fb:' + i)
    foo(i + 1) //递归调用: 在函数内部调用自己
    console.log('fe:' + i)
}
console.log('ge: ' + i)

答案:

gb: undefined
  fb: 1
  fb: 2
  fb: 3
  fe: 3
  fe: 2
  fe: 1
  ge: 1
View Code

 

posted @ 2019-10-07 22:08  猩兵哥哥  阅读(338)  评论(0编辑  收藏  举报