关于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实时监听文本框状态的方法
Apr 26 Javascript
JavaScript严格模式禁用With语句的原因
Oct 20 Javascript
JS解析XML实例分析
Jan 30 Javascript
JavaScript中用于生成随机数的Math.random()方法
Jun 15 Javascript
JavaScript的RequireJS库入门指南
Jul 01 Javascript
深入解读JavaScript中的Hoisting机制
Aug 12 Javascript
通过正则表达式获取url中参数的简单实现
Jun 07 Javascript
纯JavaScript 实现flappy bird小游戏实例代码
Sep 27 Javascript
判断颜色是否合法的正则表达式(详解)
May 03 Javascript
11行JS代码制作二维码生成功能
Mar 09 Javascript
vue.js中proxyTable 转发请求的实现方法
Sep 20 Javascript
JavaScript工具库之Lodash详解
Jun 15 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 线程安全与非线程安全版本的区别深入解析
2013/08/06 PHP
php获得客户端浏览器名称及版本的方法(基于ECShop函数)
2015/12/23 PHP
Docker配置PHP开发环境教程
2016/12/21 PHP
详解PHP防止盗链防止迅雷下载的方法
2017/04/26 PHP
JS+CSS实现的拖动分页效果实例
2015/05/11 Javascript
JS实现的N多简单无缝滚动代码(包含图文效果)
2015/11/06 Javascript
浅谈Nodejs应用主文件index.js
2016/08/28 NodeJs
老生常谈Javascript中的原型和this指针
2016/10/09 Javascript
javascript回调函数的概念理解与用法分析
2017/05/27 Javascript
基于Datatables跳转到指定页的简单实例
2017/11/09 Javascript
从0到1搭建Element的后台框架的方法步骤
2019/04/10 Javascript
jQuery zTree插件使用简单教程
2019/08/16 jQuery
Layui数据表格判断编辑输入的值,是否为我需要的类型详解
2019/10/26 Javascript
BootstrapValidator实现表单验证功能
2019/11/08 Javascript
微信小程序中的video视频实现 自定义播放按钮、封面图、视频封面上文案
2020/01/02 Javascript
vue-i18n实现中英文切换的方法
2020/07/06 Javascript
浅述python中argsort()函数的实例用法
2017/03/30 Python
JSON Web Tokens的实现原理
2017/04/02 Python
python使用两种发邮件的方式smtp和outlook示例
2017/06/02 Python
python、java等哪一门编程语言适合人工智能?
2017/11/13 Python
Django 多语言教程的实现(i18n)
2018/07/07 Python
详解Python解决抓取内容乱码问题(decode和encode解码)
2019/03/29 Python
解决Django Static内容不能加载显示的问题
2019/07/28 Python
详解python opencv、scikit-image和PIL图像处理库比较
2019/12/26 Python
如何给Python代码进行加密
2020/01/10 Python
python全栈开发语法总结
2020/11/22 Python
css3的transform中scale缩放详解
2014/12/08 HTML / CSS
巧克力领导品牌瑞士莲美国官网:Lindt Chocolate美国
2016/08/25 全球购物
会话Bean的种类
2013/11/07 面试题
党员群众路线教育实践活动剖析材料
2014/10/10 职场文书
2014年安置帮教工作总结
2014/12/11 职场文书
机关工会工作总结2015
2015/05/26 职场文书
Golang 实现超大文件读取的两种方法
2021/04/27 Golang
分享几个实用的CSS代码块
2022/06/10 HTML / CSS
如何让你的Nginx支持分布式追踪详解
2022/07/07 Servers
基于Python实现西西成语接龙小助手
2022/08/05 Golang