关于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 相关文章推荐
解决JS浮点数运算出现Bug的方法
Mar 12 Javascript
javascript中普通函数的使用介绍
Dec 19 Javascript
js控制浏览器全屏示例代码
Feb 20 Javascript
《JavaScript函数式编程》读后感
Aug 07 Javascript
jQuery实现打开页面渐现效果示例
Jul 27 Javascript
详解node nvm进行node多版本管理
Oct 21 Javascript
javascript获取图片的top N主色值方法详解
Jan 26 Javascript
js实现简单选项卡功能
Mar 23 Javascript
JS中使用new Option()实现时间联动效果
Dec 10 Javascript
echarts.js 动态生成多个图表 使用vue封装组件操作
Jul 19 Javascript
vue-quill-editor的使用及个性化定制操作
Aug 04 Javascript
antd design table更改某行数据的样式操作
Oct 31 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
php递归法读取目录及文件的方法
2015/01/30 PHP
PHP对文件夹递归执行chmod命令的方法
2015/06/19 PHP
[原创]php简单隔行变色功能实现代码
2016/07/09 PHP
Centos7安装swoole扩展操作示例
2020/03/26 PHP
PHP 实现链式操作
2021/03/09 PHP
用脚本调用样式的几种方法
2006/12/09 Javascript
jquery 常用操作整理 基础入门篇
2009/10/14 Javascript
JS简单的轮播的图片滚动实例
2013/06/17 Javascript
javascript删除option选项的多种方法总结
2013/11/22 Javascript
js判断游览器类型及版本号的代码
2014/05/11 Javascript
nodejs 提示‘xxx’ 不是内部或外部命令解决方法
2014/11/20 NodeJs
JS实现跟随鼠标的链接文字提示框效果
2015/08/06 Javascript
举例讲解JavaScript中关于对象操作的相关知识
2015/11/16 Javascript
jquery实现拖动效果(代码分享)
2017/01/25 Javascript
使用jquery判断一个元素是否含有一个指定的类(class)实例
2017/02/12 Javascript
利用node.js制作命令行工具方法教程(一)
2017/06/22 Javascript
使用Node.js实现ORM的一种思路详解(图文)
2017/10/24 Javascript
Intellij IDEA搭建vue-cli项目的方法步骤
2018/10/20 Javascript
微信小程序实现折线图的示例代码
2019/06/07 Javascript
Vue实例的对象参数options的几个常用选项详解
2019/11/08 Javascript
javascript中的相等操作符(==与===区别)
2019/12/21 Javascript
jQuery+ajax实现用户登录验证
2020/09/13 jQuery
[56:12]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第一场 6.3
2018/06/04 DOTA
整理Python最基本的操作字典的方法
2015/04/24 Python
Python中的ctime()方法使用教程
2015/05/22 Python
python绘制双柱形图代码实例
2017/12/14 Python
Python中浅拷贝copy与深拷贝deepcopy的简单理解
2018/10/26 Python
pandas 根据列的值选取所有行的示例
2018/11/07 Python
python GUI库图形界面开发之PyQt5布局控件QVBoxLayout详细使用方法与实例
2020/03/06 Python
纯css3实现走马灯效果
2014/12/26 HTML / CSS
2014年上半年工作自我评价
2014/01/18 职场文书
我们的节日春节活动方案
2014/08/22 职场文书
酒店端午节活动方案
2014/08/26 职场文书
2014年自愿离婚协议书范本
2014/09/25 职场文书
Go标准容器之Ring的使用说明
2021/05/05 Golang
阿里云服务器部署mongodb的详细过程
2021/09/04 MongoDB