关于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 相关文章推荐
JavaScript 事件记录使用说明
Oct 20 Javascript
jquery插件制作 自增长输入框实现代码
Aug 17 jQuery
laytpl 精致巧妙的JavaScript模板引擎
Aug 29 Javascript
JQuery异步获取返回值中文乱码的解决方法
Jan 29 Javascript
jquery简单实现网页层的展开与收缩效果
Aug 07 Javascript
微信小程序商城项目之商品属性分类(4)
Apr 17 Javascript
layui中table表头样式修改方法
Aug 15 Javascript
微信小程序实现消息框弹出动画
Apr 18 Javascript
基于Layui自定义模块的使用方法详解
Sep 14 Javascript
vue点击当前路由高亮小案例
Sep 26 Javascript
微信小程序吸底区域适配iPhoneX的实现
Apr 09 Javascript
vue 在methods中调用mounted的实现操作
Aug 07 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读取文件内容后清空文件示例代码
2014/03/18 PHP
解决php写入数据库乱码的问题
2019/09/17 PHP
Extjs学习笔记之七 布局
2010/01/08 Javascript
Jquery Ajax学习实例 向页面发出请求,返回XML格式数据
2010/03/14 Javascript
jQuery UI AutoComplete 自动完成使用小记
2010/08/21 Javascript
提高javascript效率 一次判断,而不要次次判断
2012/03/30 Javascript
JS对img进行操作(换图片/切图/轮换/停止)
2013/04/17 Javascript
jquery自定义类似$.ajax()的方法实现代码
2013/08/13 Javascript
Jquery中ajax方法data参数的用法小结
2014/02/12 Javascript
HTML页面弹出居中可拖拽的自定义窗口层
2014/05/07 Javascript
Javascript中浮点数相乘的一个解决方法
2014/06/03 Javascript
javascript使用数组的push方法完成快速排序
2014/09/15 Javascript
jQuery实现锚点scoll效果实例分析
2015/03/10 Javascript
js中的内部属性与delete操作符介绍
2015/08/10 Javascript
js日期插件dateHelp获取本月、三个月、今年的日期
2016/03/07 Javascript
AngularJS实现textarea记录只能输入规定数量的字符并显示
2016/04/26 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
2016/08/03 Javascript
浅谈键盘上回车按钮的js触发事件
2017/02/13 Javascript
关于Node.js中Buffer的一些你可能不知道的用法
2017/03/28 Javascript
JS实现针对给定时间的倒计时功能示例
2017/04/11 Javascript
原生js实现简单的焦点图效果实例
2017/12/14 Javascript
JS计算距当前时间的时间差实例
2017/12/29 Javascript
vue父组件向子组件(props)传递数据的方法
2018/01/02 Javascript
JavaScript强制类型转换和隐式类型转换操作示例
2019/05/01 Javascript
[02:08]什么藏在DOTA2 TI9“小紫本”里?斧王历险记告诉你!
2019/05/17 DOTA
Python中用Decorator来简化元编程的教程
2015/04/13 Python
Python闭包函数定义与用法分析
2018/07/20 Python
Python判断变量名是否合法的方法示例
2019/01/28 Python
HTML5中input[type='date']自定义样式与日历校验功能的实现代码
2017/07/11 HTML / CSS
日本AOKI官方商城:AOKI西装
2020/06/11 全球购物
Boolean b = new Boolean(“abcde”); 会编译错误码
2013/11/27 面试题
数控专业推荐信范文
2013/12/02 职场文书
2014年社区居委会主任重阳节讲话稿
2014/09/25 职场文书
捐款通知怎么写
2015/04/24 职场文书
初中历史教学反思
2016/02/19 职场文书
Mysql InnoDB 的内存逻辑架构
2022/05/06 MySQL