从头开始学JavaScript (九)——执行环境和作用域
原文:从头开始学JavaScript (九)——执行环境和作用域

一、执行环境:定义了变量或者函数有权访问的其他数据,决定了它们各自的行为。每个执行环境都有与之关联的变量对象。
变量对象:保存着环境中定义的变量和函数。
作用域链:保证对执行环境有权访问的所有变量和函数的有序访问。
标识符解析:沿着作用域链一级一级地搜索标识符的过程。
通过例子来说明执行环境、变量对象以及作用域链:
<script type="text/javascript">
var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
//color, anotherColor, tempColor
}
//color and anotherColor
swapColors();
}
changeColor();
// color
alert("Color is now " + color);
</script>
上述例子中的执行环境、执行流程:

画的不好,请各位看官见谅。。。。。。。
作用域链:

执行环境就像一个盒子,全局环境是最外面的盒子,里面包含着很多函数的盒子,每个函数的盒子里面又包含着它自己的子函数盒子,打开的时候是从外而内依次线性打开的,如果只打开了全局环境的盒子,那么只能看到全局环境里那些盒子以外的东西,比如全局盒子有两个子盒子(第一个盒子里面有饼干,第二个盒子里面有蛋糕)和一个小玩具,那么你只能拿到玩具,但是拿不到饼干和蛋糕。如果再继续打开了全局盒子的第一个子盒子,那么既能拿到全局变量里的玩具又能拿到饼干,但是没办法拿到蛋糕。
二、作用域
2.1延长作用域链
<script type="text/javascript">
function buildUrl() {
var qs = "?debug=true";
with(location){
var url = href + qs;
}
return url;
}
var result = buildUrl();
alert(result);
</script>
with会把location对象的所有属性和方法包含到变量对象中,并加入到作用域链的顶部。此时访问href实际上就是location.href。
with语句详解:
function initUI(){
with(document){
var bd = body,
links = getElementsByTagName("a"),
i = 0,
len = links.length;
while(i<len){
update(links[i++]);
}
getElementById("go-btn").onclick = function(){
start();
};
bd.className = "active"
}
}
这里使用with语句来避免多次书写document,看上去更高效,实际上产生了性能问题。
当代码流执行到一个with表达式时,执行环境的作用域链会被临时改变,此时with的变量对象会被创建添加到作用域链的前端,这就意味着此时函数的所有局部变量都被推入到第二个作用域链中的变量对象,因此访问代价更高了。
所以,在程序中应避免使用with语句,在这个例子中,只要简单的把document存储在一个局部变量中就可以提升性能。
function initUI(){
var doc=document
var bd = doc.body,
links = doc.getElementsByTagName("a"),
i = 0,
len = links.length;
while(i<len){
update(links[i++]);
}
doc.getElementById("go-btn").onclick = function(){
start();
};
bd.className = "active"
}
catch语句详解:
当try代码块中发生错误时,执行过程会跳转到catch语句,然后把异常对象推入一个可变对象并置于作用域的头部。在catch代码块内部,函数的所有局部变量将会被放在第二个作用域链对象中。
try{
doSomething();
}catch(ex){
alert(ex.message);
//作用域链在此处改变
}
请注意,一旦catch语句执行完毕,作用域链机会返回到之前的状态。try-catch语句在代码调试和异常处理中非常有用,因此不建议完全避免。你可以通过优化代码来减少catch语句对性能的影响。一个很好的模式是将错误委托给一个函数处理,例如:
try{
doSomething();
}catch(ex){
handleError(ex); //委托给处理器方法
}
优化后的代码,handleError方法是catch子句中唯一执行的代码。该函数接收异常对象作为参数,这样你可以更加灵活和统一的处理错误。由于只执行一条语句,且没有局部变量的访问,作用域链的临时改变就不会影响代码性能了。
2.2没有块级作用域
Javscript没有块级作用域。看下面代码:
if(true){
var myvar = "jack";
}
alert(myvar);// jack
根据上面我们讨论的,如果有块级作用域,外部是访问不到myvar的。再看下面

for (var i=0;i<5;i++){
console.log(i)
}
alert(i); // 5

对于有块级作用域的语言来说,i做为for初始化的变量,在for之外是访问不到的,这允分证明了,javascript是没有块级作用域的。
从头开始学JavaScript (九)——执行环境和作用域的更多相关文章
- 深入理解javascript中执行环境(作用域)与作用域链
深入理解javascript中执行环境(作用域)与作用域链 相信很多初学者对与javascript中的执行环境与作用域链不能很好的理解,这里,我会按照自己的理解同大家一起分享. 一般情况下,我们把执行 ...
- Javascript手记-执行环境和作用域
执行环境是javascript一个重要的概念,执行环境定义了变量有权访问其他数据决定了他们各自的行为,每个执行环境 都有一个与之关联的变量,环境中定义的所有变量和函数都保存在这个对象中,虽然我们编写的 ...
- JavaScript之执行环境及作用域
执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中.我们编写的代码是无法访问这个对象的,但解 ...
- javascript中执行环境和作用域(js高程)
执行环境(execution context,为简单起见,有时也成为“环境”)是javascript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其他数据,决定了它们各自的行为.每个执行环境 ...
- 从头开始学JavaScript (十)——垃圾收集
原文:从头开始学JavaScript (十)--垃圾收集 一.垃圾收集 1.1javascript垃圾收集机制: 自动垃圾收集,执行环境会负责管理代码执行过程中的使用的内存.而在C和C++之类的语言中 ...
- JavaScript之一: 闭包、执行环境、作用域链
这是大虾的第一篇博文,大虾试图用最直白的语言去描述出所理解的东西,大虾是菜鸟,水平有限,有误的地方希望路过的朋友们务必指正,谢谢大家了. 从读书时代一路走来,大虾在学习的时候逐渐喜欢上了去追寻根源,这 ...
- 从头开始学JavaScript (十一)——Object类型
原文:从头开始学JavaScript (十一)--Object类型 一.object类型 一个object就是一系列属性的集合,一个属性包含一个名字(属性名)和一个值(属性值). object对于在应 ...
- 从头开始学JavaScript (十二)——Array类型
原文:从头开始学JavaScript (十二)--Array类型 一.数组的创建 注:ECMAscript数组的每一项都可以保存任何类型的数据 1.1Array构造函数 var colors = ne ...
- 从头开始学JavaScript (八)——变量
原文:从头开始学JavaScript (八)--变量 一.变量分类: 基本类型值:null.undefined.number.string.Boolean: 引用类型值:保存在内存中的对象,如:Obj ...
随机推荐
- SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别
SQL中IN,NOT IN,EXISTS,NOT EXISTS的用法和差别: IN:确定给定的值是否与子查询或列表中的值相匹配. IN 关键字使您得以选择与列表中的任意一个值匹配的行. 当要获得居住在 ...
- 在Windows基础上(硬盘)安装Linux操作系统(CentOS/RedHat)
注:该方法安装CentOS ,RedHat均没有问题,其它Linux操作系统,没有尝试过. 0.创建一个fat32的盘.我分了8G给这个盘,盘符为F.F盘以后的内存所有删除,作为未分配的内存.这个留用 ...
- [LeetCode299]Bulls and Cows
题目: You are playing the following Bulls and Cows game with your friend: You write down a number and ...
- Android利用网络编程HttpClient批量上传(一个)
请尊重他人的劳动成果.转载请注明出处:Android网络编程之使用HttpClient批量上传文件 我曾在<Android网络编程之使用HTTP訪问网络资源>一文中介绍过HttpCient ...
- 了解HTML5和“她”的 API (二)
Communication(通信) Cross Document Messaging (跨文档消息通信) postMessage API origin security(源安全) chat ...
- 【原版的】PHP技术成长规划过程中猿人
PHP程序猿的技术成长规划 作者:黑夜路人(2014/10/15) 依照了解的非常多PHP/LNMP程序猿的发展轨迹.结合个人经验体会,抽象出非常多程序猿对未来的迷漫,特别对技术学习的盲目和慌乱.简单 ...
- Android setDisplayOptions 具体的使用说明
Android有几个地方使用位计算.实例Intent Flags,它们的定义View onMeasure(int widthMeasureSpec, int heightMeasureSpec),并且 ...
- Android于JNI调用列出的程序
1.安装和下载cygwin,下载Android NDK: 2.于ndk工程JNI接口设计: 3.采用C/C++实现本地方法. 4.JNI生成动态链接库.so档: 5.动态链接库副本javaprojec ...
- 复制(6)——分发者(Distributor)
如简介中提到,分发者(Distributor)是SQLServer 复制过程的核心组件.因为它是控制和执行实际的数据移动的过程,并且存放了发布(Publications)和订阅(Subscriptio ...
- 转让malloc()该功能后,发生了什么事内核?附malloc()和free()实现源
特此声明:在本文中,引用另一篇文章和帖子,结合的概括的理解malloc()函数的实现机制. 我们常常会在C程序中调用malloc()函数动态分配一块连续的内存空间并使用它们.那么,这些用户空间发生的事 ...