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 相关文章推荐
JavaScript实现标题栏文字轮播效果代码
Oct 24 Javascript
JS中正则表达式只有3种匹配模式(没有单行模式)详解
Jul 28 Javascript
用js读写cookie的简单方法(推荐)
Aug 08 Javascript
JavaScript事件用法浅析
Oct 31 Javascript
leaflet的开发入门教程
Nov 17 Javascript
node.js-v6新版安装具体步骤(分享)
Sep 06 Javascript
Vue filter介绍及其使用详解
Oct 21 Javascript
探讨Vue.js的组件和模板
Oct 27 Javascript
详解设置Webstorm 利用babel将ES6自动转码成ES5
Dec 20 Javascript
javascript合并两个数组最简单的实现方法
Sep 14 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
Mar 17 Javascript
如何使用RoughViz可视化Vue.js中的草绘图表
Jan 30 Vue.js
提高网站性能之 如何对待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错误Parse error: syntax error, unexpected end of file in test.php on line 12解决方法
2014/06/23 PHP
Linux平台PHP5.4设置FPM线程数量的方法
2016/11/09 PHP
PHP+Redis开发的书签案例实战详解
2019/07/09 PHP
基于jQuery的一个扩展form序列化到json对象
2010/12/09 Javascript
一个简单的弹性返回顶部JS代码实现介绍
2013/06/09 Javascript
用js模拟struts2的多action调用示例
2014/05/19 Javascript
JavaScript实现数据类型的相互转换
2016/03/06 Javascript
JS中dom0级事件和dom2级事件的区别介绍
2016/05/05 Javascript
bootstrap的3级菜单样式,支持母版页保留打开状态实现方法
2016/11/10 Javascript
JS对象深度克隆实例分析
2017/03/16 Javascript
Bootstrap 响应式实用工具实例详解
2017/03/29 Javascript
nodejs 子进程正确的打开方式
2017/07/03 NodeJs
利用Webpack实现小程序多项目管理的方法
2019/02/25 Javascript
[01:35]辉夜杯战队访谈宣传片—iG.V
2015/12/25 DOTA
Python网站验证码识别
2016/01/25 Python
python多进程和多线程究竟谁更快(详解)
2017/05/29 Python
解决django 新增加用户信息出现错误的问题
2019/07/28 Python
利用keras加载训练好的.H5文件,并实现预测图片
2020/01/24 Python
python实现Oracle查询分组的方法示例
2020/04/30 Python
基于python实现生成指定大小txt文档
2020/07/20 Python
利用 Canvas实现绘画一个未闭合的带进度条的圆环
2019/07/26 HTML / CSS
美国廉价机票预订网站:Cheapfaremart
2018/04/28 全球购物
WINDOWS域的具体实现方式是什么
2014/02/20 面试题
AJAX的全称是什么
2012/11/06 面试题
中文专业毕业生自荐信
2013/10/28 职场文书
培训主管的岗位职责
2013/11/23 职场文书
中学生个人自我评价
2014/02/06 职场文书
法人授权委托书
2014/04/03 职场文书
软件专业毕业生个人自我鉴定
2014/04/17 职场文书
节能环保标语
2014/06/12 职场文书
全国优秀教师事迹材料
2014/08/26 职场文书
2014年度个人工作总结
2014/11/07 职场文书
社区六一儿童节活动总结
2015/02/11 职场文书
岗位聘任协议书
2015/09/21 职场文书
职场干货:简历中的自我评价应该这样写!
2019/05/06 职场文书
关于Python OS模块常用文件/目录函数详解
2021/07/01 Python