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之原型和继承
Jul 06 Javascript
精心挑选的12款优秀的基于jQuery的手风琴效果插件和教程
Aug 22 Javascript
js下将阿拉伯数字每三位一逗号分隔(如:15000000转化为15,000,000)
Jun 02 Javascript
JavaScript自定义数组排序方法
Feb 12 Javascript
javascript中eval解析JSON字符串
Feb 27 Javascript
js获取所有checkbox的值的简单实例
May 30 Javascript
浅谈Angularjs link和compile的使用区别
Oct 21 Javascript
微信小程序  Mustache语法详细介绍
Oct 27 Javascript
浅谈jquery采用attr修改form表单enctype不起作用的问题
Nov 25 Javascript
javaScript实现鼠标在文字上悬浮时弹出悬浮层效果
Apr 12 Javascript
JavaScript动态加载重复绑定问题
Apr 01 Javascript
Vue退出登录时清空缓存的实现
Nov 12 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简单静态页生成过程
2008/03/27 PHP
php对mongodb的扩展(初出茅庐)
2012/11/11 PHP
PHP抓取、分析国内视频网站的视频信息工具类
2014/04/02 PHP
利用谷歌 Translate API制作自己的翻译脚本
2014/06/04 PHP
php命令行(cli)模式下报require 加载路径错误的解决方法
2015/11/23 PHP
PHP实现表单提交数据的验证处理功能【防SQL注入和XSS攻击等】
2017/07/21 PHP
Codeigniter里的无刷新上传的实现代码
2019/04/14 PHP
总结一些js自定义的函数
2006/08/05 Javascript
js url传值中文乱码之解决之道
2009/11/20 Javascript
jQuery操作input值的各种方法总结
2013/11/21 Javascript
Javascript 实现复制(Copy)动作方法大全
2014/06/20 Javascript
Vue.js实战之Vuex的入门教程
2017/04/01 Javascript
Js自定义多选框效果的实例代码
2017/07/05 Javascript
Vue实现带进度条的文件拖动上传功能
2018/02/23 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
VUE组件中的 Drawer 抽屉实现代码
2019/08/06 Javascript
vue监听键盘事件的相关总结
2021/01/29 Vue.js
[01:01:18]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#2COL VS LGD
2016/03/03 DOTA
Python 错误和异常小结
2013/10/09 Python
Django入门使用示例
2017/12/12 Python
Python异常处理操作实例详解
2018/08/28 Python
python七夕浪漫表白源码
2019/04/05 Python
Python Tkinter Entry和Text的添加与使用详解
2020/03/04 Python
python如何提升爬虫效率
2020/09/27 Python
python通用数据库操作工具 pydbclib的使用简介
2020/12/21 Python
python实现简单的学生管理系统
2021/02/22 Python
html5中audio支持音频格式的解决方法
2018/08/24 HTML / CSS
英国最大最好的无人机商店:Drones Direct
2019/07/12 全球购物
中海讯通笔试题
2015/09/15 面试题
怎么写好自荐信
2013/10/30 职场文书
技校个人求职信范文
2014/01/25 职场文书
采购部长岗位职责
2014/06/13 职场文书
2015年幼儿园保育工作总结
2015/05/12 职场文书
分享mysql的current_timestamp小坑及解决
2021/11/27 MySQL
PostgreSQL基于pgrouting的路径规划处理方法
2022/04/18 PostgreSQL
MySQL导致索引失效的几种情况
2022/06/25 MySQL