• 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
  • 相关阅读:
    剑指offer--50.滑动窗口的最大值
    剑指offer--49.矩阵中的路径
    剑指offer--48.机器人的运动范围
    剑指offer--47.数据流中的中位数
    剑指offer--46.字符流中第一个不重复的字符
    剑指offer--45.二叉树的深度
    剑指offer--44.两个链表的第一个公共结点
    剑指offer--43.连续子数组的最大和
    海盗分宝石问题
    C++数组名退化指针实例
  • 原文地址:https://www.cnblogs.com/hebing0415/p/11632578.html
Copyright © 2020-2023  润新知