关于JS管理作用域的问题


Posted in Javascript onApril 10, 2013

关键字:标识符、执行上下文、作用域、作用域链、变量对象、活动对象理论知识

理解JavaScript如何管理作用域和作用域链很重要。因为在作用域链中要查找的变量对象的个数直接影响标识符解析的性能。标识符在作用域链中的位置越深,查找和访问它所需的时间越长;如果作用域管理不当,就会给脚本的执行时间带来负面影响。

    当执行JavaScript代码时,JavaScript引擎会创建一个执行上下文(Execution Context)。执行上下文(有时被称为作用域)设定了代码执行时所处的环境。JavaScript引擎会在页面加载后创建一个全局的执行上下文,然后每执行一个函数时都会创建一个对应的执行上下文,最终建立一个执行上下文的堆栈,当前起作用的执行上下文在堆栈的最顶端。

    每个执行上下文都有一个与之关联的作用域链,用于解析标识符。作用域链包含一个或多个变量对象,这些对象定义了执行上下文作用域内的标识符。全局执行上下文的作用域链中只有一个变量对象,它定义了JavaScript中所有可用的全局变量和函数。当函数被创建(不是执行)时,JavaScript引擎会把创建时执行上下文的作用域链赋给函数的内部属性[[Scope]]。然后,当函数被执行时,JavaScript引擎会创建一个活动对象(Activetion Object),并在初始化时给this、arguments、命名参数和该函数的所有局部变量赋值。活动对象会出现在执行上下文作用域链的顶端,紧接其后的是函数[[scope]]属性中的对象。

   在执行代码时,JavaScript引擎通过搜索执行上下文的作用域链来解析诸如变量和函数名这样的标识符。解析标识符的过程从作用域的顶端开始,按照自上而下的顺序进行。

验证理论

function add(num1, num2) {

    return num1 + num2;

}

当这段代码执行开始时,add函数拥有一个仅包含全局变量对象的[[scope]]属性。如下图:

关于JS管理作用域的问题

在执行add函数时,JavaScript引擎会创建一个新的执行上下文和一个包含this、arguments、num1、num2的活动对象,并把活动对象添加到作用域链中。在add()函数内部运行时,JavaScript引擎需要解析函数里的num1和num2标识符。var total = add(5, 10);

关于JS管理作用域的问题

解析过程是从作用域链中的第一个对象开始,这个对象就是包含该函数局部变量的活动对象。如果在该对象中没有找到标识符,就会继续在作用域链中下一个对象里查找标识符。一旦找到标识符,查找就结束。

高效的数据存取

局部变量是JavaScript中读写最快的标识符。

一个好的经验:任何非局部变量在函数中的使用超过一次时,都应该将其存储为局部变量。

对于数组和对象,始终将那些需要频繁存取的值存储到局部变量中。

实际上每次存取HTMLCollection对象属性,都会对DOM文档进行动态查询。

如果需要对HTMLCollection对象的成员反复存取,高效的方式是将它们复制到数组里。

Javascript 相关文章推荐
JQuery操作iframe父页面与子页面的元素与方法(实例讲解)
Nov 20 Javascript
jQuery中scrollTop()方法用法实例
Jan 16 Javascript
JS与HTML结合使用marquee标签实现无缝滚动效果代码
Jul 05 Javascript
原生js实现键盘控制div移动且解决停顿问题
Dec 05 Javascript
JavaScript实现各种排序的代码详解
Aug 28 Javascript
解决VUE框架 导致绑定事件的阻止冒泡失效问题
Feb 24 Javascript
Angular 封装并发布组件的方法示例
Apr 19 Javascript
微信小程序实现折叠展开效果
Jul 19 Javascript
react native 原生模块桥接的简单说明小结
Feb 26 Javascript
深入理解 ES6中的 Reflect用法
Jul 18 Javascript
你不知道的 TypeScript 高级类型(小结)
Aug 28 Javascript
OpenLayers3加载常用控件使用方法详解
Sep 25 Javascript
js异常捕获方法介绍
Apr 10 #Javascript
Javascript 中 null、NaN和undefined的区别总结
Apr 10 #Javascript
关于IE BUG与字符串截取substr的解决办法
Apr 10 #Javascript
javascipt基础内容--需要注意的细节
Apr 10 #Javascript
使用javascipt---实现二分查找法
Apr 10 #Javascript
页面使用密码保护代码
Apr 10 #Javascript
jQuery学习笔记(4)--Jquery中获取table中某列值的具体思路
Apr 10 #Javascript
You might like
WIN98下Apache1.3.14+PHP4.0.4的安装
2006/10/09 PHP
浅析php header 跳转
2013/06/17 PHP
使用php+swoole对client数据实时更新(一)
2016/01/07 PHP
phpinfo() 中 Local Value(局部变量)Master Value(主变量) 的区别
2016/02/03 PHP
php5.3后静态绑定用法详解
2016/11/11 PHP
关于PHP虚拟主机概念及如何选择稳定的PHP虚拟主机
2018/11/20 PHP
Alliance vs Liquid BO3 第一场2.13
2021/03/10 DOTA
JavaScript 学习笔记一些小技巧
2010/03/28 Javascript
js使用eval解析json(js中使用json)
2014/01/17 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
Css3制作变形与动画效果
2015/07/24 Javascript
JavaScript正则表达式匹配 div  style标签
2016/03/15 Javascript
两种js监听滚轮事件的实现方法
2016/05/13 Javascript
vuejs2.0实现分页组件使用$emit进行事件监听数据传递的方法
2017/02/22 Javascript
关于vue-router路径计算问题
2017/05/10 Javascript
JavaScript之map reduce_动力节点Java学院整理
2017/06/29 Javascript
js禁止Backspace键使浏览器后退的实现方法
2017/09/01 Javascript
JS+CSS实现滚动数字时钟效果
2017/12/25 Javascript
使用vue实现简单键盘的示例(支持移动端和pc端)
2017/12/25 Javascript
JS实现简单的抽奖转盘效果示例
2019/02/16 Javascript
在vscode 中设置 vue模板内容的方法
2020/09/02 Javascript
[01:06:42]VP vs NewBee Supermajor 胜者组 BO3 第二场 6.5
2018/06/06 DOTA
python运行时间的几种方法
2016/06/17 Python
浅谈Django自定义模板标签template_tags的用处
2017/12/20 Python
200 行python 代码实现 2048 游戏
2018/01/12 Python
python浪漫表白源码
2019/04/05 Python
python boto和boto3操作bucket的示例
2020/10/30 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
医院护士求职自荐信格式
2013/09/21 职场文书
大学生职业生涯规划书的基本内容
2014/01/06 职场文书
升旗仪式主持词
2014/03/19 职场文书
初三班主任寄语大全
2014/04/04 职场文书
法人授权委托书公证范本
2014/09/14 职场文书
2014年初中班主任工作总结
2014/11/08 职场文书
2016年“我们的节日·清明节”活动总结
2016/04/01 职场文书
Python实现GIF动图以及视频卡通化详解
2021/12/06 Python