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 相关文章推荐
再次更新!MSClass (Class Of Marquee Scroll通用不间断滚动JS封装类 Ver 1.6)
Feb 05 Javascript
基于JQuery的简单实现折叠菜单代码
Sep 15 Javascript
采用call方式实现js继承
May 20 Javascript
javascript模拟命名空间
Apr 17 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
Jun 13 Javascript
Angualrjs和bootstrap相结合实现数据表格table
Mar 30 Javascript
基于jQuery实现图片推拉门动画效果的两种方法
Aug 26 jQuery
ES6的Fetch异步请求的实现方法
Dec 07 Javascript
Vue CLI3.0中使用jQuery和Bootstrap的方法
Feb 28 jQuery
基于Nuxt.js项目的服务端性能优化与错误检测(容错处理)
Oct 23 Javascript
vue2.0 获取从http接口中获取数据,组件开发,路由配置方式
Nov 04 Javascript
JavaScript架构localStorage特殊场景下二次封装操作
Jun 21 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的十大要点(上)
2009/02/04 PHP
PHP中trim()函数简单使用指南
2015/04/16 PHP
List Information About the Binary Files Used by an Application
2007/06/18 Javascript
fixedBox固定div漂浮代码支持ie6以上大部分主流浏览器
2014/06/26 Javascript
JS字符串的切分用法实例
2016/02/22 Javascript
快速掌握jQuery插件WebUploader文件上传
2016/11/07 Javascript
Angular工具方法学习
2016/12/26 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
JS与jQuery实现子窗口获取父窗口元素值的方法
2017/04/17 jQuery
jQuery使用正则验证15/18身份证的方法示例
2017/04/27 jQuery
nodejs multer实现文件上传与下载
2017/05/10 NodeJs
基于vue 实现表单中password输入的显示与隐藏功能
2019/07/19 Javascript
js动态获取时间的方法分析
2019/08/02 Javascript
ES6基础之数组和对象的拓展实例详解
2019/08/22 Javascript
JavaScript Event Loop相关原理解析
2020/06/10 Javascript
解决nuxt 自定义全局方法,全局属性,全局变量的问题
2020/11/05 Javascript
[02:05]DOTA2完美大师赛趣味视频之看我表演
2017/11/18 DOTA
python并发编程之线程实例解析
2017/12/27 Python
分析python请求数据
2018/08/19 Python
python 列表转为字典的两个小方法(小结)
2019/06/28 Python
python ubplot使用方法解析
2020/01/10 Python
Python 实现自动获取种子磁力链接方式
2020/01/16 Python
Python+Appium实现自动化测试的使用步骤
2020/03/24 Python
Python设计密码强度校验程序
2020/07/30 Python
理解Django 中Call Stack机制的小Demo
2020/09/01 Python
利用Storage Event实现页面间通信的示例代码
2018/07/26 HTML / CSS
美国一家著名的儿童鞋制造商:Stride Rite
2017/01/02 全球购物
新大陆软件面试题
2016/11/24 面试题
Hibernate持久层技术
2013/12/16 面试题
计算机专业自荐信
2013/10/14 职场文书
关于迟到的检讨书
2014/01/26 职场文书
金融专业毕业生自荐信
2014/06/26 职场文书
行政专员岗位职责说明书
2014/09/01 职场文书
优秀教师单行材料
2014/12/16 职场文书
清明节主题班会
2015/08/14 职场文书
vue实现可以快进后退的跑马灯组件
2022/04/08 Vue.js