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 相关文章推荐
在线编辑器中换行与内容自动提取
Apr 24 Javascript
JavaScript基础知识之数据类型
Aug 06 Javascript
ExtJs默认的字体大小改变的几种方法(自己整理)
Apr 18 Javascript
js判断运行jsp页面的浏览器类型以及版本示例
Oct 30 Javascript
jQuery实现点击后高亮背景固定显示的菜单效果【附demo源码下载】
Sep 21 Javascript
浅谈对Angular中的生命周期钩子的理解
Jul 31 Javascript
angular实现input输入监听的示例
Aug 31 Javascript
在vue中实现点击选择框阻止弹出层消失的方法
Sep 15 Javascript
JS编写兼容IE6,7,8浏览器无缝自动轮播
Oct 12 Javascript
微信小程序仿通讯录功能
Apr 09 Javascript
Vue 监听元素前后变化值实例
Jul 29 Javascript
vue调用本地摄像头实现拍照功能
Aug 14 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中json_decode()和json_encode()的使用方法
2012/06/04 PHP
php设计模式之单例、多例设计模式的应用分析
2013/06/30 PHP
给WordPress中的留言加上楼层号的PHP代码实例
2015/12/14 PHP
Zend Framework教程之Zend_Registry对象用法分析
2016/03/22 PHP
php版微信数据统计接口用法示例
2016/10/12 PHP
PHP实现一个按钮点击上传多个图片操作示例
2020/01/23 PHP
触屏中的JavaScript事件分析
2015/02/06 Javascript
jquery实现漂亮的二级下拉菜单代码
2015/08/26 Javascript
解决jquery无法找到其他父级子集问题的方法
2016/05/10 Javascript
jQuery基于toggle实现click触发DIV的显示与隐藏问题分析
2016/06/12 Javascript
jQuery无刷新上传之uploadify3.1简单使用
2016/06/18 Javascript
Node.js 实现简单的接口服务器的实例代码
2017/05/23 Javascript
JS实现websocket长轮询实时消息提示的效果
2017/10/10 Javascript
详解如何实现一个简单的 vuex
2018/02/10 Javascript
解决mpvue + vuex 开发微信小程序vuex辅助函数mapState、mapGetters不可用问题
2018/08/03 Javascript
简单了解node npm cnpm的具体使用方法
2019/02/27 Javascript
使用mixins实现elementUI表单全局验证的解决方法
2019/04/02 Javascript
JavaScript This指向问题详解
2019/11/25 Javascript
selenium+python实现1688网站验证码图片的截取功能
2018/08/14 Python
python3使用matplotlib绘制散点图
2019/03/19 Python
PyCharm2019安装教程及其使用(图文教程)
2019/09/29 Python
最小二乘法及其python实现详解
2020/02/24 Python
Django单元测试中Fixtures的使用方法
2020/02/26 Python
keras的backend 设置 tensorflow,theano操作
2020/06/30 Python
Python configparser模块应用过程解析
2020/08/14 Python
python 实现aes256加密
2020/11/27 Python
jupyter notebook远程访问不了的问题解决方法
2021/01/11 Python
css3教程之倾斜页面
2014/01/27 HTML / CSS
html5 canvas实现圆形时钟代码分享
2013/12/25 HTML / CSS
史上最全面的Java面试题汇总!
2015/02/03 面试题
创建服务型党组织实施方案
2014/02/25 职场文书
园艺师求职信
2014/03/10 职场文书
岗位竞聘书范文
2014/03/31 职场文书
甘南现象心得体会
2014/09/11 职场文书
2014年连锁店圣诞节活动方案
2014/12/09 职场文书
我是特种兵观后感
2015/06/11 职场文书