概念

作用域链的用途,是保证对执行环境有权访问的所有变量和函数的有序访问。其本质就是一个指向变量对象的指针列表。在js中,当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。然后使用arguments和其他命名参数的值来初始化函数的活动对象(activation object)。在作用域链中,外部函数的活动对象始终位于第二位,外部函数的外部函数的活动对象位于第三位,......直至作为作用域终点的全局执行环境。

(1) arguments和命名参数可以去看另一篇博客 JavaScript 神奇的参数

(2) 活动对象: 在一个函数对象被调用的时候,会创建一个活动对象。该函数的命名参数和arguments参数数组会被添加为该活动对象的属性,同时该函数体内显示声明的变量和函数,也会添加为该活动对象的属性(因为JS的提前声明机制,所以并没有立即赋值,值为undefined)。

在函数执行过程中,为了读取和写入变量的值,就需要在作用域中查找变量。看下面的例子:

 function compare(value1,value2) {
if (value1 < value2){
return -1;
}else if(value1 > value2){
return 1;
}else{
return 0;
}
} var result = compare(5,10);

以上代码先定义了compare()函数,然后在全局作用域中调用了它。当调用compare()时,会创建一个包含arguments、value1、value2的活动对象。全局执行环境的变量对象(包括result和compare)在compare() 执行环境的作用域中处于第二位。下图展示了包括上述关系的compare()函数执行时的作用域链。

从上图中可以看出compare的执行环境内部有一个属性指向当前作用域链,而compare()的活动对象就保存在作用域链的最前面(第一位)也就是下标为0的位置。全局执行环境的变量对象则处于第二位,也就是下标为1的位置。

过程大致为:在创建compare()函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。当调用compare()函数时,会为函数创建一个执行环境,然后通过复制函数的[[Scope]]属性中的对象构建起执行环境的作用域链。此后,又有一个活动对象被创建并推入执行环境作用域链的前端。对于这个例子中compare()函数的执行环境而言,其作用域中包含两个变量对象:本地活动对象全局变量对象。从这里就可以看出,作用域链的本质就是一个指向量的指针列表,它只引用但不实际包含变量对象。

JavaScript 作用域链其实很简单的更多相关文章

  1. JavaScript作用域链

    之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论都在说了解了作用域链和活动对象才能真正理解闭包,起初不以为然,后来在跟公司同事交流的时 ...

  2. JavaScript作用域链详解

    JavaScript的作用域链还是很有味道的,搞懂了这个知识点,闭包的问题也就迎刃而解咯 1.JavaScript的全局变量和局部变量 首先,先来看看js的全局变量和局部变量,js不是块级作用域,所以 ...

  3. JavaScript作用域链的理解

    前言 作用域是JavaScript一个很重要的概念,想要学好JavaScript就需要理解javascript作用域和作用域链的工作原理.这篇文章对JavaScript作用域链和作用域链做一个简单的介 ...

  4. JavaScript 作用域链图具体解释

    <script type="text/javascript"> /** * 作用域链: */ var a = "a"; function hao94 ...

  5. 深入javascript作用域链到闭包

    我之前用过闭包,用过this,虽然很多时候知道是这么一回事,但是确实理解上还不够深入.再一次看javascript高级程序设计这本书时,发现一起很多疑难问题竟然都懂了,所以总结一下一些理解,难免有错, ...

  6. javascript 作用域链及性能优化

    在JavaScript中,函数也是对象,实际上,JavaScript里一切都是对象.函数对象和其它对象一样,拥有可以通过代码访问的属性和一系列仅供JavaScript引擎访问的内部属性.其中一个内部属 ...

  7. 个人理解的javascript作用域链与闭包

    闭包引入的前提个人理解是为从外部读取局部变量,正常情况下,这是办不到的.简单的闭包举例如下: function f1(){ n=100; function f2(){ alert(n); } retu ...

  8. javascript作用域链学习笔记

    作用域链 "JavaScript中的函数运行在它们被定义的作用域里,而不是它们被执行的作用域里." --权威指南 在JavaScript中,一切皆对象,包括函数.函数对象和其它对象 ...

  9. (好文推荐)一篇文章看懂JavaScript作用域链

    闭包和作用域链是JavaScript中比较重要的概念,首先,看看几段简单的代码. 代码1: var name = "stephenchan"; var age = 23; func ...

随机推荐

  1. apache2.4 httpd.conf httpd-vhost.conf配置

    extra / httpd-vhost.conf <VirtualHost *:81> DocumentRoot "/data/sda1_data/" ServerNa ...

  2. Linux系统解析域名的先后顺序【转帖】

    Linux系统解析域名的先后顺序 gd_WWW已经在本地(/etc/hosts)进行指向,但是竟然还能解析到外网,让我百思不得其解.经过不断查找发现域名解析与以下四个文件有关: /etc/hosts ...

  3. [转]Python中__repr__和__str__区别

    class Test(object): def __init__(self, value='hello, world!'): self.data = value >>> t = Te ...

  4. Visual Studio 2010 VS IDE 编辑界面出现绿色的点 去掉绿色的空格点

    Visual Studio  2010 VS IDE 编辑界面出现绿色的点 去掉绿色的空格点 Vs乱按一顿忽然出现一堆绿色的点,我去好难看,还不知道什么鬼,查了查其实就是个 每个点表示一个空格 让他显 ...

  5. win PowerCmd命令行工具安装

    官网:http://www.powercmd.com/ 下载地址:http://www.powercmd.com/Install_PowerCmd.exe 版本信息: 输入注册码: PowerCmd ...

  6. Spark Streaming之dataset实例

    Spark Streaming是核心Spark API的扩展,可实现实时数据流的可扩展,高吞吐量,容错流处理. bin/spark-submit --class Streaming /home/wx/ ...

  7. 记一次GRPC使用报错排查

    项目一直使用grpc作为服务交互程序,其中我负责的java模块第一次引用该框架:当框架搭建好后,建立客户端代码,报错: Runable Error:java.lang.IllegalAccessErr ...

  8. Scrapy框架基本使用

    pycharm+Scrapy 距离上次使用Scrapy已经是大半年前的事情了,赶紧把西瓜皮捡回来.. 简单粗暴上爬取目标: 初始URL:http://quotes.toscrape.com/ 目标:将 ...

  9. ubuntu linux修改文件所属用户(owner属主)和组(groud属组、用户组)

    使用chown命令可以修改文件或目录所属的用户: 命令格式:sudo chown 用户 目录或文件名 例如:sudo chown -R griduser /home/dir1  (把home目录下的d ...

  10. 运行opatch lsinventory

    http://blog.itpub.net/4227/viewspace-704451/ 运行opatch lsinventory 注意执行opatch lsinventory的路径: > $O ...