首页 > web前端 > js教程 > 正文

JS 执行环境、作用域链、变量对象和活动对象的关系

php是最好的语言
发布: 2018-07-27 14:57:17
原创
3057人浏览过

JS执行环境

执行环境(execution context,ec)或执行上下文,是js中一个极为重要的概念

执行环境分为三种(全局执行环境,函数执行环境,evel()执行环境)

js为每一个执行环境关联了一个变量对象。环境中定义的所有变量和函数都保存在这个对象中

EC的组成

当JavaScript代码执行的时候,会进入不同的执行环境(执行上下文),这些执行环境会构成了一个执行环境栈(执行上下文栈)(Execution context stack,ECS)。见下图:
1.png

变量对象

变量对象(VO):变量对象即包含变量的对象,除了我们无法访问它外,和普通对象没什么区别。变量对象存储了在上下文中定义的变量和函数声明

变量对象和活动对象(AO)

  1. 活动对象和变量对象其实是一个东西,只是变量对象是规范上的或者说是引擎实现上的,不可在 JavaScript 环境中访问,只有到当进入一个执行上下文中,这个执行上下文的变量对象才会被激活,所以才叫 activation object

,而只有被激活的变量对象,也就是活动对象上的各种属性才能被访问。

  1. 活动对象是在进入函数执行环境时刻被创建的,它通过函数的 arguments 属性初始化。arguments 属性值是 Arguments 对象。

变量对象和活动对象的关系

未进入执行阶段之前,变量对象(VO)中的属性都不能访问!但是进入执行阶段之后,变量对象(VO)转变为了活动对象(AO),里面的属性都能被访问了,然后开始进行执行阶段的操作。

它们其实都是同一个对象,只是处于执行环境的不同生命周期。

    AO 实际上是包含了 VO 的。因为除了 VO 之外,AO 还包含函数的 parameters,以及 arguments 这个特殊对象。也就是说 AO 的确是在进入到执行阶段的时候被激活,但是激活的除了 VO 之外,还包括函数执行时传入的参数和 arguments 这个特殊对象。
登录后复制

      AO = VO + function parameters + arguments

执行环境分析

全局执行环境是最外围的执行环境,全局执行环境被认为是window对象,因此所有的全局变量和函数都作为window对象的属性和方法创建的。
js的执行顺序是根据函数的调用来决定的,当一个函数被调用时,该函数环境的变量对象就被压入一个环境栈中。而在函数执行之后,栈将该函数的变量对象弹出,把控制权交给之前的执行环境变量对象。

eg:

    var scope = "global"; 
      function fn1(){
         return scope; 
      }
      function fn2(){
         return scope;
      }
      fn1();
      fn2();
登录后复制

演示如下:

2.png

Find JSON Path Online
Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online 193
查看详情 Find JSON Path Online

[[Scope]]  作用域

变量的作用域

变量的作用域就两种:全局变量和局部变量

    全局作用域:最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的:eg:
登录后复制
          var outerVar = "outer";
          function fn(){
              console.log(outerVar);
      }
          fn();//result:outer
登录后复制
    局部作用域:局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的
登录后复制
     function fn(){
         var innerVar = "inner";
      }
      fn();
      console.log(innerVar);// ReferenceError: innerVar is not defined
登录后复制
    注意:函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量!
登录后复制
    function fn(){
            age = 18;
        }
        fn();
        console.log(age);// 18
登录后复制

再来看一个有趣的现象:

      var scope = "global";
      function fn(){
         console.log(scope);//result:undefined
         var scope = "local";
         console.log(scope);//result:local;
      }
      fn();
登录后复制

分析:第一个输出居然是undefined,原本以为它会访问外部的全局变量(scope=”global”),但是并没有。这可以算是javascript的一个特点,只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量“提前声明”,他就等价于下面的代码:

     var scope = "global";
      function fn(){
         var scope;//提前声明了局部变量
         console.log(scope);//result:undefined
         scope = "local";
         console.log(scope);//result:local;
      }
      fn();
登录后复制

[[Scopr Chain]]  作用域链

理解:根据在内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,这就是作用域链

上面给出了环境变量。下面仔细分析下作用域链

当某个函数第一次被调用时,就会创建一个执行环境(execution context)以及相应的作用域链,并把作用域链赋值给一个特殊的内部属性([scope])。然后使用this,arguments(arguments在全局环境中不存在)和其他命名参数的值来初始化函数的活动对象(activation object)。当前执行环境的变量对象始终在作用域链的第0位。以上述执行环境分析的小例子为例进行图解:当第一次调用fn1时。

3.png

解析:可以看到fn1活动对象里并没有scope变量,于是沿着作用域链(scope chain)向后寻找,结果在全局变量对象里找到了scope,所以就返回全局变量对象里的scope值。

再分析下面的代码:

    function outer(){
         var scope = "outer";
         function inner(){
            return scope;
         }
         return inner;
      }
      var fn = outer();
      fn();
登录后复制

4.png

总结

说实话,这节真的是很难,现在还是似懂非懂,不知道在学前端的小伙伴你们觉得呢?如果你们觉得这节学会了,可以给我留言,我是真心不懂这节的内容,希望有会的小伙伴可以给我点帮助!谢谢!

相关文章:

浅谈javascript中执行环境(作用域)与作用域链

老生常谈原生JS执行环境与作用域

相关视频:

js高级面向对象和组件开发视频教程

以上就是JS 执行环境、作用域链、变量对象和活动对象的关系的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号