JS 作用域(执行环境)与作用链---JS 学习笔记(二)
一 作用域(执行环境)
作用域:定义了变量和函数有权访问的其他数据,决定了他们各自的行为。--------《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 学习笔记(二)的更多相关文章
- js的闭包中关于执行环境和作用链的理解
首先讲一讲执行环境: 执行环境按照字面上来理解就是指目前代码执行所在的环境. 当JavaScript代码执行的时候,会进入不同的执行上下文,这些执行上下文会构成了一个执行上下文栈(Execution ...
- (O)JS:执行环境、变量对象、活动对象和作用域链(原创)
var a=1; function b(x){ var c=2; console.log(x); } b(3); ·执行环境(execution context),也称为环境.执行上下文.上下文环境. ...
- js的执行环境学习笔记
js执行全局代码或者执行函数代码的时候,首先进行准备,然后再执行.准备阶段,就是创建执行环境的阶段. 1.执行环境 当一段js代码遇到解释器的时候,比如浏览器打开一段js代码时候,第一件事并不是马上执 ...
- js高级程序设计(第三版)学习笔记(第一版)
ecma:欧洲计算机制造商协会iso/iec:国际标准化和国际电工委员会 dom级别(10*)文档对象模型1:DOM核心(映射基于xml文档)与dom html(在dom核心基础上)2:对鼠标,事件, ...
- 纯JS实现KeyboardNav(学习笔记)二
纯JS实现KeyboardNav(学习笔记)二 这篇博客只是自己的学习笔记,供日后复习所用,没有经过精心排版,也没有按逻辑编写 这篇主要是添加css,优化js编写逻辑和代码排版 GitHub项目源码 ...
- AJax 学习笔记二(onreadystatechange的作用)
AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...
- 蒟蒻的长链剖分学习笔记(例题:HOTEL加强版、重建计划)
长链剖分学习笔记 说到树的链剖,大多数人都会首先想到重链剖分.的确,目前重链剖分在OI中有更加多样化的应用,但它大多时候是替代不了长链剖分的. 重链剖分是把size最大的儿子当成重儿子,顾名思义长链剖 ...
- JavaScript之JS的执行环境和作用域
一.执行环境是JavaScript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为,每个执行环境都有一个与之关联的变量对象(variable object),环境 ...
- js的执行环境及作用域
主要的是执行环境和作用域链. 执行环境 执行环境定义了变量或函数有权访问的其他数据,每个函数都有一个执行环境,每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个变量对象中, ...
随机推荐
- AIX stack_hard参数
OS:AIX 7.1 root.oracle.grid用户查看资源限制,其中stack受限,需要在/etc/security/limits中增加stack_hard = -1,受硬限制限制! [ora ...
- python 图像处理,画一个正弦函数
import numpy as np from PIL import Image import matplotlib.pyplot as plt import math size = 300 new_ ...
- 详解iBaits中SqlMapClientTemplate的使用
Apache iBatis(现已迁至Google Code下发展,更名为MyBatis)是当前IT项目中使用很广泛的一个半自动ORM框架,区别于Hibernate之类的全自动框架,iBatis对数据库 ...
- TerminateProcess实现关闭任意程序
#include <Windows.h> #include <tchar.h> int WINAPI _tWinMain(HINSTANCE hInstance, HINSTA ...
- 如何防止自己网站的图片被其他网站所盗用,从而导致自己网站流量的损失【apache篇】
站图片被其他网站盗用的问题我想在业务逻辑代码上解决恐怕是有点困难的. 而apache上只需要简单的配置就可以解决这个问题. 解决方法: 1.确定你的apache加载了mod_setenvif模块(li ...
- 对int类型的数据,如何让获取长度
下面为大家写一个列子 int a = 124;<br> Integer a1 = a;//转换为包装类Integer<br> System.out.println(a1.t ...
- 2017 5 31 php面向过程 面向对象1
面向过程的语法定义变量:定义函数:使用变量(输出,赋值,等)调用函数:流程控制(if,switch,for,while等) 面向对象的语法1,定义类:定义类的语法中,只有这3种代码:1.1定义属性(变 ...
- 《高性能Mysql》解读---Mysql的事务和多版本并发
1.base:ACID属性,并发控制 2.MySql事务的隔离级别有哪些,含义是什么? 3.锁知多少,读锁,写锁,排他锁,共享锁,间隙锁,乐观锁,悲观锁. 4.Mysql的事务与锁有什么关联?MySq ...
- Python之io概念
""" 同步,异步: 强调结果,调用者最终是否得到想要的结构 阻塞非阻塞: 强调时间是否等待 io二个阶段 1.数据准备阶段 2.内核空间复制回用户空间缓冲区阶段 发生i ...
- .Net Core技术研究-Span<T>和ValueTuple<T>
性能是.Net Core一个非常关键的特性,今天我们重点研究一下ValueTuple<T>和Span<T>. 一.方法的多个返回值的实现,看ValueTuple<T> ...