说明:以下代码说明和原理都是基于ES5和非严格模式进行

执行环境和作用域链

执行环境定义了变量或函数有权访问的其他数据。每个执行环境都有与之关联的变量对象,一般情况下我们无法访问变量对象,解析器会在我们访问变量或函数时在后台使用它。

执行环境的所有代码执行完毕后,该环境被销毁,其中的变量和函数定义被销毁。web浏览器的全局执行环境是window对象,所有的全局变量和函数,都是window的属性和方法,全局执行环境会在程序退出时才会销毁,也就是关闭网页或者浏览器关闭的时候。

代码在任何环境执行中都会生成一个作用域链,它可以保证当前环境下变量和函数的有序访问。作用域的前端始终是当前执行环境的变量对象,简单的说,就是变量搜索从当前执行环境向上搜索。

函数的变量对象是他的活动对象,最开始也就是arguments对象。作用域链的下一个变量对象来自外部包含环境,再下一个来自下一个包含环境,直到全局执行环境,也就是说全局执行环境是作用域链的末端。

var color = 'blue'function changeColor () {var anotherColor = 'red' function swapColors() { var tColor = anotherColor; anotherColor = color; color = tColor; // 这里可以访问三个变量 } // 这里可以访问color anotherColor swapColors()}// 这里只能访问colorchangeColor()

图中矩形为执行环境,内部环境可以通过作用域链访问所有的外部环境,反之不行。每个执行环境都向上搜索作用域链来查找变量和函数。所以swapColors包含三个变量对象,自己的,changeColor的,window的,changeColor只包含两个,自己的和window。

所以,作用域只能按照顺序向上搜索变量。

ps:函数参数也是变量。规则和普通声明变量一致。

延长作用域链

执行环境只用全局和局部两种,但还是有办法在作用域前端添加一个变量对象,典型的例子有:

  1. try。。。catch。。。语句
  2. with语句
try { var a = 123;a.b()} catch (e){console.log(a,e)}console.log(a) // 123console.log(e) // 报错,说明访问不到e变量,所以try和catch不在一个作用域。// 这里的catch语句延长了作用域链,所以catch语句中,向上访问到了a变量。// 最后的两个打印说明了catch的确是延长了作用域链所以才能访问到a。function buildUrl () {var qs = "?a=123" with(location) { var url = href + qs; } console.log(url) // 有结果}// with 会把指定的对象添加到作用域链前端,所以,访问href时,直接就在当前环境中找到。而不会向上了。

js没有块级作用域

也就是{}无法形成封闭的作用域。

if (true) {var color = 'blur'}console.log(color); // 'blue'

声明变量

如果初始化变量时没有使用var等关键字声明,那么将会是全局变量。

function add(num1, num2) {sum = num1 + num2 return sum}add(1,2)console.log(sum) // 3// 所以在初始化变量时必须声明。

查询标示符

前面已经说过,变量查询是沿着作用域链向上找,找到的第一个变量作为结果返回。所以作用域链上存在同名变量时会存在变量遮蔽。

var name = 'foo'function bar () {var name = 'bar' console.log('bar')}bar() // 'bar'

从作用域链看闭包

var name = 'window' function foo () {var name = 'foo' return function () { console.log(name) }}var bar = foo() // 执行这一句时,因为返回了一个方法,方法是一个引用对象,导致foo方法执行完成后,没办法// 销毁它自身执行环境中的变量(因为无法回收方法的引用)。// 既然无法销毁执行环境那么作用域链就不会消失,当执行bar方法时就会沿着最开始的作用域链向上查找。bar() // 'foo' 可以访问到foo中的变量。(所以这里不是window)

js中执行php语句_重温JS中的执行环境和作用域链相关推荐

  1. ef 执行mysql语句_在EF中执行SQL语句

    一.为什么要在EF中执行SQL语句 使用EF操作数据库,可以避免写SQL语句,完成使用Linq实现,但为什么还要在EF中执行SQL语句呢.如果要写SQL语句,完全可以使用ADO.NET来操作数据库.这 ...

  2. java 执行ddl语句_在JDBC中,如何知道DDL语句是否成功执行?

    我正在尝试使用JDBC在Oracle 11g数据库上执行DDL语句.我现在用的是这样做boolean execute(String SQL)的的Statement类. 以下是执行查询并尝试确定查询结果 ...

  3. python中if嵌套语句_讲解Python中if语句的嵌套用法

    可能有这样一种情况,当你想检查其他条件后一个条件解析为真.在这种情况下,可以使用嵌套的if结构. 在嵌套的 if 语句结构,可以在一个 if... elif... else 结构里面可有另外一个 if ...

  4. python控制语句中的条件语句_『Python』条件控制语句

    Loading... ## 1. 条件语句 ``` Python条件语句是通过一条或者多条语句的执行结果(True或False)来决定执行的代码块. ``` ``` 在Python中, 指定任何非0和 ...

  5. java switch case语句_在Java中使用switch Case语句的例子

    当我们有多个选项,并且需要为每个选项执行不同的任务时,就需要使用Switch case语句. Switch case语句的语法如下-switch (variable or an integer exp ...

  6. java的goto语句_语法 - Java中是否有goto语句?

    语法 - Java中是否有goto语句? 我对此感到困惑. 我们大多数人都被告知Java中没有任何goto语句. 但我发现它是Java中的关键词之一. 哪里可以使用? 如果它不能使用,那么为什么它作为 ...

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

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

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

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

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

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

最新文章

  1. 模板方法模式与策略模式的区别
  2. 你知道怎么使用OpenCV检测篮球运动员吗?
  3. oracle命令行导出、导入dmp文件
  4. CompletableFuture源码详解之java.util.concurrent.CompletableFuture#runAsync(java.lang.Runnable)
  5. 建设网站需要的Bootstrap介绍与操作
  6. core控制器属性注入的用处_asp.net-core – 如何使用Autofac和ASP.NET Core在控制器上启用属性注入?...
  7. 【Gson】2.2.4 StackOverflowError 异常
  8. 邀请 The Invitation
  9. ElementUI:tree组件背景色、鼠标hover悬浮背景色、选中背景色修改
  10. 宋宝华Linux培训笔记-Linux内存管理
  11. Windows7计算机的程序文件名,Win7怎么显示文件后缀名_Win7显示文件的扩展名-192路由网...
  12. Unity 打开文件夹
  13. MSCOMM串口控件在VS2010中的使用
  14. H.264——H.264的基本介绍
  15. python风变编程培训骗局
  16. 运营干货!分销系统怎么做?
  17. HTTP 500 - Internal Server Error 服务器内部错误
  18. 绩效考核-项目经理绩效考核指标
  19. 数据结构(十一)——递归
  20. 约瑟夫环问题-python代码

热门文章

  1. 数控直线工作台直线控制系统的simulink仿真
  2. jdk下没有java源码_openJDK之如何下载各个版本的openJDK源码
  3. AcWing 888. 求组合数 IV(高精度求组合数问题)
  4. 第十二届蓝桥杯大赛软件赛决赛题解
  5. java程序开发个人笔记_Java程序开发入门笔记
  6. 集群提交HBase代码报错:Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.HBaseConfiguratio
  7. Activity管理类,随时随地退出应用程序
  8. [Pro]斐波那契数列阿【斐波那契数列】
  9. R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(一,基本原理)
  10. 内核态文件操作【转】