一  作用域(执行环境)

作用域:定义了变量和函数有权访问的其他数据,决定了他们各自的行为。--------《JS高级程序设计》4.2

好难理解啊~参考了参考尤克希的博客内容,大体上理解了作用域。

作用域:规定了函数和变量的可用的有效的范围。这样的好处是,避免了命名冲突;确定何时销毁他们,释放内存。这个作用域中所有的函数和对象,都保存在变量对象里。每个作用域都有这样一个变量对象。但是我们编写的代码是无法访问到这个对象的,解析器在处理数据时会在后台使用它。

作用域分为两类:全局作用域和函数作用域。

全局作用域是最外围的一个作用域。根据 ECMAScript 实现所在的宿主环境不同,表示作用域的对象也不一样。在 Web 浏览器中,全局作用域是 Window 对象,因此所有全局变量和函数都是作为 window 对象的属性和方法创建的。当某一个作用域中所有的代码都执行完以后,作用域被销毁, 作用域里面的变量和函数,也随之销毁。(全局执行环境直到应用程序退出----例如关闭网页或者浏览器------这时才被销毁)  ----------- 《JS高级程序设计》4.2

环境栈:每个函数都有自己的作用域,当执行流进入一个函数时,函数的作用域就会被推入一个环境栈中。函数执行完毕后,这个函数的作用域被环境栈弹出,把控制权交还给之前的作用域。

在一个页面中,第一次载入JS代码时创建一个全局执行环境,当调用一个 JavaScript 函数时,该函数就会进入相应的执行环境。如果又调用了另外一个函数(或者递归地调用同一个函数),则又会创建一个新的执行环境,并且在函数调用期间执行过程都处于该环境中。当调用的函数返回后,执行过程会返回原始执行环境。因而,运行中的 JavaScript 代码就构成了一个执行环境栈。(参考笨蛋的座右铭)。

举个例子,下面程序的环境栈如下图:

var cloth = 'shirt';

function f1() {
var anotherCloth = 'pants'; function f2() {
var drink = 'juice';
}
  f2();
}

f1();

二  作用域链

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

标识符解析是沿着作用域链一级级搜索标识符的过程。搜索过程始终都是从作用域链的前段开始,然后逐级的向后回溯,直到找到标识符为止(如果找不到标识符,通常会导致错误发生。)

-----《JS高级程序设计》4.2

举例来理解:

 var color = 'blue';

 function changeColor() {
var anotherColor = "red" function swapColors() {
var tempColor = anotherColor;
anotherColor = color;
color = tempColor; // 这里可以访问 color、anotherColor 和 tempColor
} // 这里可以访问 color 和 anotherColor。不能访问 tempColor swapColors()
} // 这里只能访问 color changeColor()

上面代码在执行的时候有三个作用域:全局作用域、changeColor() 作用域和 swapColors() 作用域。他们的作用域链如下图:

作用域链的本质是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。

三  块级作用域

块级作用域,就是在 for、if  等里面定义的变量,在 for、if 执行完毕以后,这些变量也会被销毁。ES6 之前的版本,是没有块级作用域的。ES6 新增加了 let 和 const 关键字,就有了块级作用域。例如下面的代码:

 if (true) {
var color = 'blue';
} alert(color); // 'blue' color 变量在 if 语句执行完以后并没有被销毁if 语句执行完以后,还会在外面访问到 if 里面的 color变量。
1 if (true) {
2 let color = 'blue';
3 }
4
5 alert(color); // color is not defined color 变量在 if 语句执行完毕以后,被销毁,外部访问不到 if 语句块里面定义的 color 变量。
 for (var i=0; i < 10; i++) {
var a = 1;
} alert(i) // 10 for (const i=0; i < 10; i++) {
var a = 1;
} alert(i) // invalid assignment to const `i'

未解决的问题:

if 语句用 const 实现不了块级作用域,for 语句用 let 实现不了会计作用域。这个疑惑还要后续再查找资料补充。

补充结果:let 用在块作用域定义变量,而 const 在块作用域定义常量。即在块作用域中,一旦使用 const a = 1;那么,在块作用域中,就不能再给 a 赋值别的值了。因为,此时 a 已经是一个常量了。

JS 作用域(执行环境)与作用链---JS 学习笔记(二)的更多相关文章

  1. js的闭包中关于执行环境和作用链的理解

    首先讲一讲执行环境: 执行环境按照字面上来理解就是指目前代码执行所在的环境. 当JavaScript代码执行的时候,会进入不同的执行上下文,这些执行上下文会构成了一个执行上下文栈(Execution ...

  2. (O)JS:执行环境、变量对象、活动对象和作用域链(原创)

    var a=1; function b(x){ var c=2; console.log(x); } b(3); ·执行环境(execution context),也称为环境.执行上下文.上下文环境. ...

  3. js的执行环境学习笔记

    js执行全局代码或者执行函数代码的时候,首先进行准备,然后再执行.准备阶段,就是创建执行环境的阶段. 1.执行环境 当一段js代码遇到解释器的时候,比如浏览器打开一段js代码时候,第一件事并不是马上执 ...

  4. js高级程序设计(第三版)学习笔记(第一版)

    ecma:欧洲计算机制造商协会iso/iec:国际标准化和国际电工委员会 dom级别(10*)文档对象模型1:DOM核心(映射基于xml文档)与dom html(在dom核心基础上)2:对鼠标,事件, ...

  5. 纯JS实现KeyboardNav(学习笔记)二

    纯JS实现KeyboardNav(学习笔记)二 这篇博客只是自己的学习笔记,供日后复习所用,没有经过精心排版,也没有按逻辑编写 这篇主要是添加css,优化js编写逻辑和代码排版 GitHub项目源码 ...

  6. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  7. 蒟蒻的长链剖分学习笔记(例题:HOTEL加强版、重建计划)

    长链剖分学习笔记 说到树的链剖,大多数人都会首先想到重链剖分.的确,目前重链剖分在OI中有更加多样化的应用,但它大多时候是替代不了长链剖分的. 重链剖分是把size最大的儿子当成重儿子,顾名思义长链剖 ...

  8. JavaScript之JS的执行环境和作用域

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

  9. js的执行环境及作用域

    主要的是执行环境和作用域链. 执行环境 执行环境定义了变量或函数有权访问的其他数据,每个函数都有一个执行环境,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个变量对象中, ...

随机推荐

  1. Openshift 错误解决 "修改docker cgroup driver"

    一.Openshift 错误解决 "修改docker cgroup driver" 一.错误如下 failed to run Kubelet: failed to create k ...

  2. 2019.4.14 python基础30

    前面学习的变量,数据类型(整型,浮点数,布尔),序列(字符串,列表,元祖,字典,集合) ,可以看做是数据的组织方式.数据可以看做是“砖块”! 流程控制语句是代码的组织方式,可以看做是“混凝土” 一个完 ...

  3. ZY

    2017*****1022:我是石翟夫:我的爱好是计算机: 我的码云个人主页是:https://gitee.com/S_DiF/events 我的第一个项目地址是:https://gitee.com/ ...

  4. eclipse二、保证svn导入的项目正常运行

    1.环境说明 eclipse4.11 需要jdk1.8支持 公司项目大都jdk1.6与jdk1.5 为保持公司项目正常运行而配置jdk运行场景 2.window需按照jdk1.8.jdk1.6 jdk ...

  5. vue axios中文文档详解

    英文文档:https://github.com/axios/axios 参考:https://www.jb51.net/article/123485.htm

  6. (.NET高级课程笔记)泛型总结

    泛型总结 1.引入泛型:延迟声明,即在声明的时候没有指定参数类型,只有当调用的时候才会确定 其参数类型(架构师的理念:推迟一切可以推迟的) 2.如何声明和使用泛型 3.泛型的好处和原理 4.泛型类.泛 ...

  7. kafka安装教程

    今天需要在新机器上安装一个kafka集群,其实kafka我已经装了十个不止了,但是没有一个是为生产考虑的,因此比较汗颜,今天好好地把kafka的安装以及配置梳理一下: 1,kafka版本选取: 现在我 ...

  8. Can't find msguniq. Make sure you have GNU gettext tools 0.15 or newer installed

    Python Django生成国际化和本地化.po文件步骤1.在settings文件中,添加一下内容: LANGUAGES = ( ('zh-hans', ugettext_lazy('Simplif ...

  9. 2017.12.7 URAT 串口通信

    波特率就是发送二进制数据位的速率, 习惯上用 baud 表示, 即我们发送一位二进制数据的持续时间=1/baud. 在通信之前, 单片机 1 和单片机 2 首先都要明确的约定好它们之间的通信波特率, ...

  10. 菜鸟初学redis(二)

    如果你的redis可以在myeclipse上运行小demo了,那么可以继续学习了 redis Java String 实例 string是redis最基本的类型,一个key对应一个value. str ...