一、执行环境:定义了变量或者函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有与之关联的变量对象。

变量对象:保存着环境中定义的变量和函数。

作用域链:保证对执行环境有权访问的所有变量和函数的有序访问。

标识符解析:沿着作用域链一级一级地搜索标识符的过程。

通过例子来说明执行环境、变量对象以及作用域链:

 1  <script type="text/javascript">
 2         var color = "blue";
 3         function changeColor(){
 4             var anotherColor = "red";
 5             function swapColors(){
 6                 var tempColor = anotherColor;
 7                 anotherColor = color;
 8                 color = tempColor;
 9                 //color, anotherColor, tempColor
10             }
11             //color and anotherColor
12             swapColors();
13         }
14         changeColor();
15         // color
16         alert("Color is now " + color);
17     </script>

上述例子中的执行环境、执行流程:

画的不好,请各位看官见谅。。。。。。。

作用域链:

执行环境就像一个盒子,全局环境是最外面的盒子,里面包含着很多函数的盒子,每个函数的盒子里面又包含着它自己的子函数盒子,打开的时候是从外而内依次线性打开的,如果只打开了全局环境的盒子,那么只能看到全局环境里那些盒子以外的东西,比如全局盒子有两个子盒子(第一个盒子里面有饼干,第二个盒子里面有蛋糕)和一个小玩具,那么你只能拿到玩具,但是拿不到饼干和蛋糕。如果再继续打开了全局盒子的第一个子盒子,那么既能拿到全局变量里的玩具又能拿到饼干,但是没办法拿到蛋糕。

二、作用域

2.1延长作用域链

虽然执行环境只有两种——全局作用域和函数作用域,但是还是可以通过某种方式来延长作用域链。因为有些语句可以在作用域链的顶部增加一个临时的变量对象。
有两种情况会发生这种现象:
1、try-catch语句的catch块;创建一个新的变量对象,其中包含的是被抛出的错误对象的声明。
2、with语句;将指定的对象添加到作用域链中。
 1     <script type="text/javascript">
 2         function buildUrl() {
 3             var qs = "?debug=true";
 4             with(location){
 5                 var url = href + qs;
 6             }
 7             return url;
 8         }
 9         var result = buildUrl();
10         alert(result);
11     </script>

with会把location对象的所有属性和方法包含到变量对象中,并加入到作用域链的顶部。此时访问href实际上就是location.href。

with语句详解:

 1 function initUI(){
 2    with(document){
 3         var bd = body,
 4         links =  getElementsByTagName("a"),
 5         i = 0,
 6         len = links.length;
 7         while(i<len){
 8               update(links[i++]);
 9         }
10         getElementById("go-btn").onclick = function(){
11               start();
12         };
13         bd.className = "active"
14    }
15 }

这里使用with语句来避免多次书写document,看上去更高效,实际上产生了性能问题。

当代码流执行到一个with表达式时,执行环境的作用域链会被临时改变,此时with的变量对象会被创建添加到作用域链的前端,这就意味着此时函数的所有局部变量都被推入到第二个作用域链中的变量对象,因此访问代价更高了。

所以,在程序中应避免使用with语句,在这个例子中,只要简单的把document存储在一个局部变量中就可以提升性能。

 1 function initUI(){
 2         var doc=document
 3         var bd = doc.body,
 4         links =  doc.getElementsByTagName("a"),
 5         i = 0,
 6         len = links.length;
 7         while(i<len){
 8               update(links[i++]);
 9         }
10         doc.getElementById("go-btn").onclick = function(){
11               start();
12         };
13         bd.className = "active"
14
15 }

catch语句详解:

当try代码块中发生错误时,执行过程会跳转到catch语句,然后把异常对象推入一个可变对象并置于作用域的头部。在catch代码块内部,函数的所有局部变量将会被放在第二个作用域链对象中。

1 try{
2 doSomething();
3 }catch(ex){
4       alert(ex.message);
5 //作用域链在此处改变
6  } 

请注意,一旦catch语句执行完毕,作用域链机会返回到之前的状态。try-catch语句在代码调试和异常处理中非常有用,因此不建议完全避免。你可以通过优化代码来减少catch语句对性能的影响。一个很好的模式是将错误委托给一个函数处理,例如:

1 try{
2 doSomething();
3  }catch(ex){
4 handleError(ex); //委托给处理器方法
5 } 

优化后的代码,handleError方法是catch子句中唯一执行的代码。该函数接收异常对象作为参数,这样你可以更加灵活和统一的处理错误。由于只执行一条语句,且没有局部变量的访问,作用域链的临时改变就不会影响代码性能了。

2.2没有块级作用域

Javscript没有块级作用域。看下面代码:

if(true){var myvar = "jack";    }alert(myvar);// jack

根据上面我们讨论的,如果有块级作用域,外部是访问不到myvar的。再看下面

for (var i=0;i<5;i++){console.log(i)    }alert(i); // 5

对于有块级作用域的语言来说,i做为for初始化的变量,在for之外是访问不到的,这充分证明了,javascript是没有块级作用域的。

转载于:https://www.cnblogs.com/yxField/p/4226089.html

从头开始学JavaScript (九)——执行环境和作用域相关推荐

  1. 从头开始学JavaScript (五)——操作符(二)

    原文:从头开始学JavaScript (五)--操作符(二) 一.乘性操作符 1.乘法:*      乘法操作符的一些特殊规则: 如果操作数都是数值,按照常规的乘法计算,如果乘积超过了ECMAscri ...

  2. JavaScript执行环境及作用域(一)——执行环境栈和作用域链机制

    2019独角兽企业重金招聘Python工程师标准>>> 执行环境是JavaScript中最为重要的一个概念,每个执行环境都有一个与之关联的变量对象,执行环境中所有的变量和函数都保存在 ...

  3. 从头再学 JavaScript 系列前言

    说实话想写这个系列已经很久了,对于每一个学习前端的同学来说,JavaScript 都是必须要掌握的,但是实际上对很多同学而言,特别是刚入门或者入门时间不长的同学,对 JS 的认识并不深.大部分仅仅停留 ...

  4. javaScript执行环境、作用域链与闭包

    一.执行环境 执行环境定义了变量和函数有权访问的其他数据,决定了他们各自的行为:每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中.虽然我们编写的代码无法访问这个对象 ...

  5. 执行环境,作用域链,闭包

    执行环境 执行环境是JavaScript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存 ...

  6. VO、AO、执行环境和作用域链

    1.变量对象(variable object) 原文:Every execution context has associated with it a variable object. Variabl ...

  7. 闭包、执行环境、作用域链

    闭包是指有权访问另一个函数作用域中的变量的函数,创建的常见方式就是在一个函数内部创建另一个函数. 我们来理解下执行环境和作用域链: 1.执行环境有全局执行环境和函数执行环境之分. 2.每次进入一个新的 ...

  8. js中执行php语句_重温JS中的执行环境和作用域链

    说明:以下代码说明和原理都是基于ES5和非严格模式进行 执行环境和作用域链 执行环境定义了变量或函数有权访问的其他数据.每个执行环境都有与之关联的变量对象,一般情况下我们无法访问变量对象,解析器会在我 ...

  9. JavaScript语言精粹--执行环境及作用域,this

    1.执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为. 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中. 虽然我们无法访问,但是解析器在处理数据时 ...

最新文章

  1. python图像分割重组_通过PYTHON来实现图像分割详解
  2. WWDC 2011 苹果全球开发者大会【中文】
  3. web页面到ajax,页面使用ajax加载页面后如果运行其中的js,webpack如何多页面展示...
  4. 西电计算机达标测试挂科保研,西电竞赛保研
  5. 电影《你好,李焕英》进入全球票房榜前100
  6. flowable 多人签收_业务流程 BPM、工作流引擎、Flowable、Activiti
  7. react sql格式化_为SQL Server数据库损坏做准备; 初步React与分析
  8. 安装openstack(pike版本)nova节点,yum安装报错分析
  9. 极域电子书包课堂管理系统怎么控屏_极域电子书包课堂管理系统
  10. Executors Java编程规范插件提示手动创建线程池的解决办法
  11. 吐槽最新的chrome浏览器.
  12. 小姐姐手机被偷后发朋友圈,结果…
  13. SSL 1653 数字游戏
  14. Linux挖矿病毒查杀
  15. alert(1) (haozi.me)靶场练习
  16. 【人工智能】【1024】谷歌量子计算突破登Nature封面,号称200秒顶超算10000年!
  17. 与蜂窝连接的无人机的空地干扰缓解
  18. 飞腾64核服务器cpu芯片,【今日头条】飞腾64核CPU适配百度昆仑AI处理器:全国产的AI体系登场...
  19. unity碰撞检测函数,碰撞信息获取,触发检测,使用粒子系统创建火焰,创建动画(火光闪烁),导航系统,通过导航系统控制人物移动,控制摄像机的跟随,控制角色动画播放
  20. 计算机基础之Linux

热门文章

  1. 实现一个输入程序,接收从 键盘读入的字符串。当字符串中所含字符个数少于程序设定的上限时,输出这个字符串;否则抛出MyStringException1异常,在异常处理中要求重新输入新的字符串或者中断程序
  2. 持久层和数据访问层_什么是持久层? JDBC 演变的 Mybatis 架构分析
  3. NLP工具包(Albert+BiLSTM+CRF)
  4. 数据缺失,如何智能修复?第一名方案源码分享
  5. GBDT原理及利用GBDT构造新的特征-Python实现
  6. u盘读写测试_aigo U395固态U盘评测,速度可能会吓到你,价格很良心
  7. 矩阵的奇异值分解_线性代数31——奇异值分解
  8. 计算机组成原理实用教程第3版课后答案,计算机组成原理实用教程课后习题答案.docx...
  9. 用newlisp管理windows下的nginx
  10. Win 7 下IE 的cookie 以及 Favorites 地址