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 相关文章推荐
js word表格动态添加代码
Jun 07 Javascript
js的touch事件的实际引用
Oct 13 Javascript
js获取浏览器基本信息大全
Nov 27 Javascript
jQuery中的pushStack实现原理和应用实例
Feb 03 Javascript
JS实现下拉菜单赋值到文本框的方法
Aug 18 Javascript
jQuery+css实现的时钟效果(兼容各浏览器)
Jan 27 Javascript
node.js中grunt和gulp的区别详解
Jul 17 Javascript
Vue-cli-webpack搭建斗鱼直播步骤详解
Nov 17 Javascript
写给小白看的JavaScript异步
Nov 29 Javascript
JavaScript求一组数的最小公倍数和最大公约数常用算法详解【面向对象,回归迭代和循环】
May 07 Javascript
layer父页获取弹出层输入框里面的值方法
Sep 02 Javascript
原生JS实现相邻月份日历
Oct 13 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伪造referer的方法 利用referer防止图片盗链
2014/01/20 PHP
php常用的安全过滤函数集锦
2014/10/09 PHP
PHP批量删除jQuery操作
2017/07/23 PHP
浅谈PHP中pack、unpack的详细用法
2018/03/12 PHP
PHP5.0~5.6 各版本兼容性cURL文件上传功能实例分析
2018/05/11 PHP
PHP设计模式入门之状态模式原理与实现方法分析
2020/04/26 PHP
ExtJS GridPanel 根据条件改变字体颜色
2010/03/08 Javascript
jQuery-Easyui 1.2 实现多层菜单效果的代码
2012/01/13 Javascript
JS或jQuery获取ASP.NET服务器控件ID的方法
2015/06/08 Javascript
JavaScript中的parse()方法使用简介
2015/06/12 Javascript
jQuery实现鼠标滑过点击事件音效试听
2015/08/31 Javascript
jQuery插件实现表格隔行变色及鼠标滑过高亮显示效果代码
2016/02/25 Javascript
基于d3.js实现实时刷新的折线图
2016/08/03 Javascript
用iframe实现不刷新整个页面上传图片的实例
2016/11/18 Javascript
简单实现js悬浮导航效果
2017/02/05 Javascript
创建简单的node服务器实例(分享)
2017/06/23 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
Angular(5.2->6.1)升级小结
2018/12/27 Javascript
详解Js里的for…in和for…of的用法
2019/03/28 Javascript
小程序外卖订单界面的示例代码
2019/12/30 Javascript
解决vue-photo-preview 异步图片放大失效的问题
2020/07/29 Javascript
vue+axios 拦截器实现统一token的案例
2020/09/11 Javascript
[10:42]Team Liquid Vs Newbee
2018/06/07 DOTA
在Python的Django框架中更新数据库数据的方法
2015/07/17 Python
Python中json格式数据的编码与解码方法详解
2016/07/01 Python
Pycharm 实现下一个文件引用另外一个文件的方法
2019/01/17 Python
在OpenCV里实现条码区域识别的方法示例
2019/12/04 Python
Keras使用tensorboard显示训练过程的实例
2020/02/15 Python
Django多层嵌套ManyToMany字段ORM操作详解
2020/05/19 Python
Expected conditions模块使用方法汇总代码解析
2020/08/13 Python
详解pycharm自动import所需的库的操作方法
2020/11/30 Python
html5基础标签(html5视频标签 html5新标签用法)
2013/12/30 HTML / CSS
爱尔兰家电数码商城:Currys PC World爱尔兰
2016/07/23 全球购物
澳洲的服装老品牌:SABA
2018/02/06 全球购物
四风问题自查自纠工作情况报告
2014/10/28 职场文书
护理专业毕业自我鉴定
2019/08/12 职场文书