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 相关文章推荐
用JavaScript页面不刷新时全选择,全删除(GridView)
Apr 14 Javascript
JavaScript中变量提升 Hoisting
Jul 03 Javascript
Jquery选中或取消radio示例
Sep 29 Javascript
巧用jquery解决下拉菜单被Div遮挡的相关问题
Feb 13 Javascript
javascript继承的六大模式小结
Apr 13 Javascript
基于jQuery实现的扇形定时器附源码下载
Oct 20 Javascript
Bootstrap菜单按钮及导航实例解析
Sep 09 Javascript
基于JavaScript实现的插入排序算法分析
Apr 14 Javascript
微信小程序对接七牛云存储的方法
Jul 30 Javascript
总结js函数相关知识点
Feb 27 Javascript
如何以Angular的姿势打开Font-Awesome详解
Apr 22 Javascript
详解Angular中实现自定义组件的双向绑定的两种方法
Nov 23 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开发的一些注意点总结
2010/10/12 PHP
php支持中文字符串分割的函数
2015/05/28 PHP
Laravel5.* 打印出执行的sql语句的方法
2017/07/24 PHP
浅谈PHP中如何实现Hook机制
2017/11/14 PHP
javascript 自定义事件初探
2009/08/21 Javascript
JS连接SQL数据库与ACCESS数据库的方法实例
2013/11/21 Javascript
玩转方法:call和apply
2014/05/08 Javascript
javascript实现获取字符串hash值
2015/05/10 Javascript
jQuery实现返回顶部效果的方法
2015/05/29 Javascript
原生JS实现图片轮播与淡入效果的简单实例
2016/08/21 Javascript
knockoutjs动态加载外部的file作为component中的template数据源的实现方法
2016/09/01 Javascript
JavaScript中的遍历详解(多种遍历)
2017/04/07 Javascript
[js高手之路]图解javascript的原型(prototype)对象,原型链实例
2017/08/28 Javascript
jQuery实现的事件绑定功能基本示例
2017/10/11 jQuery
vue项目引入Iconfont图标库的教程图解
2018/10/24 Javascript
JavaScript中十种一步拷贝数组的方法实例详解
2019/04/22 Javascript
[46:48]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第三局
2016/02/25 DOTA
[42:32]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第二场 10.28
2020/10/28 DOTA
为Python的web框架编写前端模版的教程
2015/04/30 Python
编写Python爬虫抓取豆瓣电影TOP100及用户头像的方法
2016/01/20 Python
python-itchat 统计微信群、好友数量,及原始消息数据的实例
2019/02/21 Python
Python中面向对象你应该知道的一下知识
2019/07/10 Python
django settings.py 配置文件及介绍
2019/07/15 Python
Python企业编码生成系统之主程序模块设计详解
2019/07/26 Python
Django 实现前端图片压缩功能的方法
2019/08/07 Python
Python中断多重循环的思路总结
2019/10/04 Python
python tkinter之 复选、文本、下拉的实现
2020/03/04 Python
使用matplotlib动态刷新指定曲线实例
2020/04/23 Python
python实现发送QQ邮件(可加附件)
2020/12/23 Python
纯CSS实现颜色渐变效果(包含环形渐变、线性渐变、彩虹效果等)
2014/05/07 HTML / CSS
Raffaello Network西班牙:意大利拉斐尔时尚购物网
2019/03/12 全球购物
SQL Server的固定数据库角色都有哪些?对应的服务器权限有哪些?
2013/05/18 面试题
工作表扬信的范文
2014/01/10 职场文书
六年级情感作文之500字
2019/10/23 职场文书
导游词之淮安明祖陵
2019/11/25 职场文书
golang中的并发和并行
2021/05/08 Golang