js 函数的执行环境和作用域链的深入解析


Posted in Javascript onNovember 01, 2009

第一步. 定义后:每个已定义函数,都有一个内在属性[scope],其对应一个对象的列表,列表中的对象仅能内部访问。

例如:建立一个全局函数A,那么A的[Scope]内部属性中只包含一个全局对象(Global Object),而如果我们在A中创建一个新的函数B,那么B的[Scope]属性中就包含两个对象,函数A的Activation Object对象在前面,全局对象(Global Object)排在后面。

简而言之,一个函数的[Scope]属性中对象列表的顺序是上一层函数的Activation Object对象,然后是上上层的,一直到最外层的全局对象。

第二步.执行时:当一个函数被执行的时候,会自动创建一个可以执行的对象(Execution Object),并同时绑定一个作用域链(Scope Chain)。作用域链会通过下面两个步骤来建立,用于进行标识符解析。

首先,将函数对象[Scope]内部属性中的对象,按顺序复制到作用域链Scope Chain中。
其次,在函数执行时,会创建一个新的Activation Object对象,这个对象中包含了this、参数(arguments)、局部变量(包括命名的参数)的定义,这个Activation Object对象会被置于作用域链的最前面。
所以在Scope Chain中最后顺序是本函数的Activation Object,然后是上层函数的Activation Object,再上上层的Activation Object,一直到Global Object。

当执行js代码的过程中,遇到一个标识符,就会根据标识符的名称,在执行上下文(Execution Context)的作用域链中进行搜索。从作用域链的第一个对象(该函数的Activation Object对象)开始,如果没有找到,就搜索作用域链中的下一个对象,如此往复,直到找到了标识符的定义。如果在搜索完作用域中的最后一个对象,也就是全局对象(Global Object)以后也没有找到,则会抛出一个错误,提示undefined。

由此而来的建议:

1. 尽量使用局部变量,这不仅仅是涉及到私有属性的问题,局部的变量从以上过程中可以看到,能够减少搜索的时间(注:在一般的情况下,不包括浏览器的优化行为)。

2. 避免使用with语句。因为它会修改执行上下文(Execution Context)的作用域链,在最前面添加一个对象(Variable Object)。同理,对于try-catch语句中的catch语句块也类似。

Javascript 相关文章推荐
在修改准备发的批量美化select+可修改select时,在非IE下发现了几个问题
Jan 09 Javascript
EasyUI的treegrid组件动态加载数据问题的解决办法
Dec 11 Javascript
Jquery 复选框取值兼容FF和IE8(测试有效)
Oct 29 Javascript
JavaScript开发人员的10个关键习惯小结
Dec 05 Javascript
深入理解JavaScript 函数
Jun 06 Javascript
功能强大的Bootstrap组件(结合js)
Aug 03 Javascript
jquery.zclip轻量级复制失效问题
Jan 08 Javascript
jQuery居中元素scrollleft计算方法示例
Jan 16 Javascript
JavaScript模板引擎实现原理实例详解
Dec 14 Javascript
vue安装遇到的5个报错及解决方法
Jun 12 Javascript
JS把字符串格式的时间转换成几秒前、几分钟前、几小时前、几天前等格式
Jul 10 Javascript
Vue性能优化的方法
Jul 30 Javascript
提高网站性能之 如何对待JavaScript
Oct 31 #Javascript
JavaScript Sort 表格排序
Oct 31 #Javascript
DOM 脚本编程中的兄弟节点
Oct 31 #Javascript
javascript GUID生成器实现代码
Oct 31 #Javascript
json 实例详细说明教程
Oct 31 #Javascript
json 入门基础教程 推荐
Oct 31 #Javascript
jquery text()要注意啦
Oct 30 #Javascript
You might like
PHP在Web开发领域的优势
2006/10/09 PHP
PHP图片上传代码
2013/11/04 PHP
总结一些PHP中好用但又容易忽略的小知识
2017/06/02 PHP
jquery简单瀑布流实现原理及ie8下测试代码
2013/01/23 Javascript
js通过元素class名字获取元素集合的具体实现
2014/01/06 Javascript
javascript定义变量时有var和没有var的区别探讨
2014/07/21 Javascript
jquery ui resize 中border-box的bug修正
2015/04/26 Javascript
Javascript函数的参数
2015/07/16 Javascript
jquery表单验证插件formValidator使用方法
2016/04/01 Javascript
jquery选择器中的空格与大于号>、加号+与波浪号~的区别介绍
2016/06/24 Javascript
JavaScript职责链模式概述
2016/09/17 Javascript
javascript另类方法实现htmlencode()与htmldecode()函数实例分析
2016/11/17 Javascript
详解AngularJS2 Http服务
2017/06/26 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
微信小程序使用canvas自适应屏幕画海报并保存图片功能
2019/07/25 Javascript
js如何验证密码强度
2020/03/18 Javascript
Python的迭代器和生成器使用实例
2015/01/14 Python
Python解析excel文件存入sqlite数据库的方法
2016/11/15 Python
Python 函数list&read&seek详解
2019/08/28 Python
Pycharm debug调试时带参数过程解析
2020/02/03 Python
python实现替换word中的关键文字(使用通配符)
2020/02/13 Python
Python中and和or如何使用
2020/05/28 Python
美国知名艺术画网站:Art.com
2017/02/09 全球购物
Gap英国官网:Gap UK
2018/07/18 全球购物
中国旅游网站:途牛旅游网
2019/09/29 全球购物
Roxy俄罗斯官方网站:冲浪和滑雪板的一切
2020/06/20 全球购物
数据库什么时候应该被重组
2012/11/02 面试题
中专生求职自荐信范文
2013/12/22 职场文书
20岁生日感言
2014/01/13 职场文书
工程技术员岗位职责
2014/03/02 职场文书
群众路线个人剖析材料及整改措施
2014/11/04 职场文书
2014年会计工作总结
2014/11/27 职场文书
情人节活动总结范文
2015/02/05 职场文书
2015年试用期自我评价范文
2015/03/10 职场文书
2015年行政执法工作总结
2015/05/23 职场文书
K8s部署发布Golang应用程序的实现方法
2021/07/16 Golang