美文网首页
映像-作用域

映像-作用域

作者: zhaochengqi | 来源:发表于2018-06-15 14:20 被阅读15次

    概念赏析:

    执行环境(execution context)
    有时也可叫做执行上下文,定义了当前环境下可访问的其他数据。执行环境有 全局执行环境函数执行环境(eval执行环境类比函数执行环境)。

    变量对象(variable object)
    变量对象是与执行上下文对应的概念,上下文中定义的所有成员都保存在这个对象中。
    该对象仅供解析器使用,开发者无法访问

    活动对象 (activation object)
    活动对象是在函数被调用时创建的,最开始时只包含一个变量:arguments 对象。
    函数执行环境将其活动对象作为变量对象

    环境栈 (context stack)
    每个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被压入一个环境栈中。在函数执行之后,栈将其环境弹出(环境被销毁,保存在其中的变量和函数定义也随之销毁;但闭包会改变这一行为),把控制权交还给之前的执行环境。

    全局执行环境
    在Web浏览器中被认为是window对象(window对象作为变量对象?)。
    因此所有全局变量、函数都是作为window对象的属性和方法创建的。全局执行环境是最外围一个执行环境,直到应用关闭才会被销毁

    作用域链 (scope chain)
    当代码在一个环境中执行时,会创建一个作用域链来指向变量对象,以保证对执行环境有权访问的变量、函数的有序访问。
    作用域链的前端始终是当前执行代码所在环境的变量对象,而作用域链中的下一个变量对象来自外部(包含)环境,一直延续到全局执行环境。全局执行环境的 变量对象 始终是作用域链中的最后一个对象

    图 1. 作用域

    LHS vs RHS
    标识符解析是沿着作用域链一级一级地搜索标识符的过程,始终从作用域链的前端开始,逐级向后回溯。查找类型有两种:LHS和RHS。
    L 和 R 的含义是 赋值操作的左侧或右侧。

    • 当执行LHS查询时,如果找不到目标变量,就会在全局作用域中创建一个具有该名称的变量(非严格模式下,严格模式下同样会抛出 ReferenceError )。

    • 如果RHS查询在作用域中找不到所需变量,引擎会抛出 ReferenceError 。


    词法作用域

    大部分标准语言编译器的第一个工作阶段叫作词法化(也叫单词化)。词法化的过程会对源代码中的字符进行检查,如果是有状态的解析过程,还会赋予单词语义。

    作用域共有两种主要的工作模型:

    • 词法作用域,被大多数编程语言所采用的。
    • 动态作用域,仍有一些编程语言在使用(比如 Bash 脚本、Perl 中的一些模式等)。

    JavaScript 中的作用域就是词法作用域。
    简单地说,词法作用域就是定义在词法阶段的作用域。也可以理解为,词法作用域是由你在写代码时将变量和块作用域写在哪里来决定的,因此当词法分析器处理代码时会保持作用域不变(大部分情况下是这样的,eval、with会修改作用域)。

    看一下例子:

    function foo(){
      console.log(a)
    }
    function bar(){
      var a = 3;
      foo()
    }
    var a = 2
    bar() // 输出 2
    //词法作用域让foo的作用域链前端的下面是全局变量对象。
    //如果JS具有动态作用域,那么理论上应该输出3,因为顺着调用栈可以找到bar的作用域。
    

    由此可见,JS作用域链的生成是基于代码中的作用域嵌套,而不是基于栈调用的。

    相关文章

      网友评论

          本文标题:映像-作用域

          本文链接:https://www.haomeiwen.com/subject/lzdpeftx.html