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 相关文章推荐
JQuery 学习笔记 选择器之六
Jul 23 Javascript
JS TextArea字符串长度限制代码集合
Oct 31 Javascript
JS实现一个按钮的方法
Feb 05 Javascript
javascript产生随机数方法汇总
Jan 25 Javascript
浅谈使用splice函数对数组中的元素进行删除时的注意事项
Dec 04 Javascript
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
Jan 22 Javascript
Vue.js开发环境快速搭建教程
Mar 17 Javascript
JS中跳出循环的示例代码
Sep 14 Javascript
Bootstrap Paginator+PageHelper实现分页效果
Dec 29 Javascript
详解Vue中使用插槽(slot)、聚类插槽
Apr 12 Javascript
Vuex实现数据共享的方法
Dec 20 Javascript
javascript实现京东登录显示隐藏密码
Aug 02 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
使用TinyButStrong模板引擎来做WEB开发
2007/03/16 PHP
中国站长站 For Dede4.0 采集规则
2007/05/27 PHP
如何用php获取文件名后缀
2013/06/09 PHP
19个Android常用工具类汇总
2014/12/30 PHP
Laravel + Elasticsearch 实现中文搜索的方法
2020/02/02 PHP
极酷的javascirpt,让你随意编辑任何网页
2007/02/25 Javascript
Jquery中dialog属性小记
2010/09/03 Javascript
返回对象在当前级别中是第几个元素的实现代码
2011/01/20 Javascript
ajax中get和post的说明及使用与区别
2012/12/23 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
2013/01/23 Javascript
一个JavaScript获取元素当前高度的实例
2014/10/29 Javascript
readonly和disabled属性的区别
2015/07/26 Javascript
Vue.js系列之项目结构说明(2)
2017/01/03 Javascript
bootstrap datetimepicker 日期插件在火狐下出现一条报错信息的原因分析及解决办法
2017/03/08 Javascript
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
Vue中建立全局引用或者全局命令的方法
2017/08/21 Javascript
Vue在页面数据渲染完成之后的调用方法
2018/09/11 Javascript
JavaScript实现的弹出遮罩层特效经典示例【基于jQuery】
2019/07/10 jQuery
js轮播图之旋转木马效果
2020/10/13 Javascript
[54:05]DOTA2-DPC中国联赛定级赛 SAG vs iG BO3第一场 1月9日
2021/03/11 DOTA
[06:45]DOTA2-DPC中国联赛 正赛 Magma vs LBZS 选手采访
2021/03/11 DOTA
python实现redis三种cas事务操作
2017/12/19 Python
Python按照list dict key进行排序过程解析
2020/04/04 Python
python用分数表示矩阵的方法实例
2021/01/11 Python
CSS3 画基本图形,圆形、椭圆形、三角形等
2016/09/20 HTML / CSS
我有一个char * 型指针正巧指向一些int 型变量, 我想跳过它们。 为什么如下的代码((int *)p)++; 不行?
2013/05/09 面试题
音乐学个人的自荐书范文
2013/11/26 职场文书
计算机专业应届生求职信
2014/04/06 职场文书
区级文明单位申报材料
2014/05/15 职场文书
员工合理化建议书
2014/05/19 职场文书
2014年幼儿园个人工作总结
2014/11/10 职场文书
早上好问候语大全
2015/11/10 职场文书
2019年度行政文员工作计划范本!
2019/07/04 职场文书
2019最新版试用期劳动合同模板!
2019/07/04 职场文书
MySQL索引失效的典型案例
2021/06/05 MySQL
深入解读Java三大集合之map list set的用法
2021/11/11 Java/Android