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中==与===操作符的比较
Mar 21 Javascript
通过js获取div的background-image属性
Oct 15 Javascript
jQuery对Select的操作大集合(收藏)
Dec 28 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
Apr 17 Javascript
浅析Bootstrap组件之面板组件
May 04 Javascript
基于jQuery实现点击列表加载更多效果
May 31 Javascript
js简单实现网页换肤功能
Apr 07 Javascript
JavaScript实现跟随滚动缓冲运动广告框
Jul 15 Javascript
Vue动态获取width的方法
Aug 22 Javascript
js中的数组对象排序分析
Dec 11 Javascript
微信小程序实现多选框全选与反全选及购物车中删除选中的商品功能
Dec 17 Javascript
JavaScript实现五子棋小游戏
Oct 26 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实现从ftp服务器上下载文件树到本地电脑的程序
2009/02/10 PHP
php中用memcached实现页面防刷新功能
2014/08/19 PHP
php+ajax实现无刷新分页的方法
2014/11/04 PHP
日常整理PHP中简单的图形处理(经典)
2015/10/26 PHP
CI框架网页缓存简单用法分析
2018/12/26 PHP
JS对URL字符串进行编码/解码分析
2008/10/25 Javascript
浅析ajax请求json数据并用js解析(示例分析)
2013/07/13 Javascript
输入自动提示搜索提示功能的javascript:sugggestion.js
2013/09/02 Javascript
JavaScript实现列出数组中最长的连续数
2014/12/29 Javascript
浅析JS操作DOM的一些常用方法
2016/05/13 Javascript
深入理解$.each和$(selector).each
2016/05/15 Javascript
JS Array创建及concat()split()slice()的使用方法
2016/06/03 Javascript
基于Javascript实现的不重复ID的生成器
2016/12/25 Javascript
Vue-Router进阶之滚动行为详解
2017/09/13 Javascript
vue-cli中vue本地实现跨域调试接口
2019/01/16 Javascript
浅谈Vuex注入Vue生命周期的过程
2019/05/20 Javascript
何时/使用 Vue3 render 函数的教程详解
2020/07/25 Javascript
[03:39]DOTA2英雄梦之声_第05期_幽鬼
2014/06/23 DOTA
python中如何使用正则表达式的集合字符示例
2017/10/09 Python
tensorflow学习教程之文本分类详析
2018/08/07 Python
python使用phoenixdb操作hbase的方法示例
2019/02/28 Python
使用Python自动生成HTML的方法示例
2019/08/06 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
2020/04/18 Python
浅谈Python 递归算法指归
2019/08/22 Python
keras 读取多标签图像数据方式
2020/06/12 Python
没编程基础可以学python吗
2020/06/17 Python
pycharm远程连接服务器并配置python interpreter的方法
2020/12/23 Python
HTML5的表单(绝对特别强大的功能)使用示例
2013/06/20 HTML / CSS
html5绘制时钟动画
2014/12/15 HTML / CSS
家庭睡衣和家庭用品:Little Blue House
2018/03/18 全球购物
澳大利亚珍珠首饰购物网站:Vayo Pearls
2019/03/11 全球购物
EJB包括(SessionBean,EntityBean)说出他们的生命周期,及如何管理事务的?
2013/02/17 面试题
大学生党员个人剖析材料
2014/10/08 职场文书
公司转让协议书
2016/03/19 职场文书
简单了解 MySQL 中相关的锁
2021/05/25 MySQL
Oracle删除归档日志及添加定时任务
2022/06/28 Oracle