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 相关文章推荐
使用jquery的ajax需要注意的地方dataType的设置
Aug 12 Javascript
JavaScript闭包函数访问外部变量的方法
Aug 27 Javascript
javascript无刷新评论实现方法
May 13 Javascript
jquery实现点击展开列表同时隐藏其他列表
Aug 10 Javascript
javascript字符串替换函数如何一次性全部替换掉
Oct 30 Javascript
bootstrap模态框跳转到当前模板页面 框消失了而背景存在问题的解决方法
Nov 30 Javascript
JSONP跨域请求
Mar 02 Javascript
windows下vue-cli及webpack搭建安装环境
Apr 25 Javascript
详解Vue+axios+Node+express实现文件上传(用户头像上传)
Aug 10 Javascript
Vue-cli3项目引入Typescript的实现方法
Oct 18 Javascript
vue 中的 render 函数作用详解
Feb 28 Javascript
PHP 502bad gateway原因及解决方案
Nov 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
如何提高MYSQL数据库的查询统计速度 select 索引应用
2007/04/11 PHP
php处理json格式数据经典案例总结
2016/05/19 PHP
Yii 2.0自带的验证码使用经验分享
2017/06/19 PHP
Laravel 自带的Auth验证登录方法
2019/09/30 PHP
Laravel实现ApiToken认证请求
2019/10/14 PHP
javascript的函数
2007/01/31 Javascript
让回调函数 showResponse 也带上参数的代码
2007/08/13 Javascript
使用Microsoft Ajax Minifier减小JavaScript文件大小的方法
2010/04/01 Javascript
jQuery学习笔记之jQuery+CSS3的浏览器兼容性
2015/01/19 Javascript
JavaScript实现图片轮播的方法
2015/07/31 Javascript
jquery datatable服务端分页
2016/08/31 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
2016/12/16 Javascript
两种简单的跨域方法(jsonp、php)
2017/01/02 Javascript
Vue.js 2.0 移动端拍照压缩图片上传预览功能
2017/03/06 Javascript
vue.js 初体验之Chrome 插件开发实录
2017/05/13 Javascript
JavaScript内置对象math,global功能与用法实例分析
2019/06/10 Javascript
vue中使用 pako.js 解密 gzip加密字符串的方法
2019/06/10 Javascript
[55:44]完美世界DOTA2联赛决赛 FTD vs Phoenix 第二场 11.08
2020/11/11 DOTA
python实现web方式logview的方法
2015/08/10 Python
python计算列表内各元素的个数实例
2018/06/29 Python
python使用Matplotlib画饼图
2018/09/25 Python
Python I/O与进程的详细讲解
2019/03/08 Python
Python编程快速上手——疯狂填词程序实现方法分析
2020/02/29 Python
Python3.9.0 a1安装pygame出错解决全过程(小结)
2021/02/02 Python
总结30个CSS3选择器
2017/04/13 HTML / CSS
HTML5 图片预加载的示例代码
2020/03/25 HTML / CSS
Derek Rose官网:英国高档睡衣、家居服和内衣品牌
2020/01/18 全球购物
华为智利官方商店:Huawei Chile
2020/05/09 全球购物
关于VPN
2012/06/10 面试题
物流管理专业职业生涯规划书
2014/01/06 职场文书
员工薪酬福利制度
2014/01/17 职场文书
社区两委对照检查材料
2014/08/23 职场文书
2014年留守儿童工作总结
2014/12/10 职场文书
小学生纪律委员竞选稿
2015/11/19 职场文书
Nginx配置文件详解以及优化建议指南
2021/09/15 Servers
浅谈css清除浮动(clearfix和clear)的用法
2023/05/21 HTML / CSS