执行环境定义了变量或函数有权访问的其他数据,决定了它们的各自行为。每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中,虽然我们无法访问这个对象,但是解析器在处理数据时会在后台使用它。

全局执行环境是最外围的一个环境,在web浏览器中,全局执行环境被认为是window对象,因此所有全局变量和函数都是作为window对象的属性和方法创建的。

某个执行环境中的所有代码执行完毕后,该环境被销毁,保存在其中的所有变量和函数定义也随之全部被销毁。

当代码在一个环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。

作用域链的前端,始终都是当前执行的代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象。活动对象在最开始时只包含一个变量,即arguments对象(这个对象在全局环境中是不存在的)。作用域链的下一个变量对象来自于包含(外部)环境,在下一个变量外部环境对象则来自下一个包含环境,这样一直延续到全局执行环境,全局执行环境的对象始终都是作用域链中的最后一个对象。

示例1:

var color = "blue";
function changeColor(){
if (color === "blue"){
color = "red";
} else {
color = "blue";
}
}
changeColor();
alert("Color is now " + color);//Color is now red

解析:函数changeColor()的作用域包含两个对象,它自己的变量对象(其中定义着arguments对象)和全局环境的变量对象(color)。

示例2:

var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
//color, anotherColor, and tempColor are all accessible here
}
//color and anotherColor are accessible here, but not tempColor
swapColors();
}
changeColor();
//anotherColor and tempColor aren't accessible here, but color is
alert("Color is now " + color);

解析:上面一共有3个执行环境:全局环境,changeColor()的局部环境和swapColors()的局部环境。

全局环境中有一个变量color和一个函数changeColor()。

changeColor()的局部环境中有一个名为anotherColor的变量和一个名为swapColor()的函数,也可以访问全局环境中的变量color。

swapColor()的局部环境中有一个变量tempColor,该变量只能在这个环境中访问到,同时还能访问前面两个执行环境中的所有变量。

下面的图片就展示了上面例子的作用域链:

JavaScript中没有块级作用域

在其它语言中,由花括号封闭的代码块都有自己的作用域,但是在JavaScript中却不是这样的。

示例3:

if(true){
var color="blue";
}
alert(color);//"blue" 当上面代码执行完了,变量color并没有被销毁,而是一直存在于全局环境中了。 for(var i=0;i<10;i++){
doSomething(i);
}
alert(i);//10 对于有块级作用域的语言来说,for语句初始化变量的表达式所定义的变量,只会存在于循环的环境之中。而对于JavaScript来说,由for语句创建的变量i即使在for循环结束后,也依旧会存在于循环外部的执行环境中。

变量申明

在JavaScript中,使用var申明的变量会自动添加到最接近的环境中。在函数内部,最接近的环境就是函数的局部环境。

如果在申明变量省略var这个关键字,即使在函数运行完了,在外部也能够访问到这个变量,就好像变成全局变量是的。

示例4:

使用var申明的
function add(num1, num2) {
var sum = num1 + num2;
return sum;
}
var result = add(10, 20); //30
alert(sum); //causes an error since sum is not a valid variable 没有使用var申明的
function add(num1, num2) {
sum = num1 + num2;
return sum;
} var result = add(10, 20); //30
alert(sum); //30

最新文章

  1. IOS学习之NSNotificationCenter消息机制
  2. java Servlet小结
  3. 复利计算器(4)——jQuery界面美化、自动补全
  4. Java学习总结(二)----Java语言基础
  5. 看完 《重来(REWORK)》
  6. 第五篇 :微信公众平台开发实战Java版之如何获取公众号的access_token以及缓存access_token
  7. Spring 事务配置管理,简单易懂,详细 [声明式]
  8. cocos2dx ease 公式
  9. CATransform3D 讲解
  10. 高质量程序设计指南C/C++语言——有了malloc/free为什么还要new/delete?
  11. 高精度运算专题-输出函数与字符串转数字函数(Output function and the string to number function)
  12. C++接口的定义与实现的详细过程
  13. 源码安装xadmin及使用
  14. Python_Excel文件操作
  15. get、put、post、delete含义与区别
  16. gdb常用的指令
  17. SpringBoot系列: Spring MVC视图方法的补充
  18. Can&#39;t connect to local MySQL server through socket &#39;/var/lib/mysql/mysql.sock&#39; 解决办法
  19. linux系统分析工具续-SystemTap和火焰图(Flame Graph)
  20. 【linux】linux下shell命令 多个变量在命令中的引用 以及重新赋值给新的变量

热门文章

  1. The Internet Communications Engine (Ice) 跨平台异构通讯方案 第一弹-ICE简介
  2. linux系统下部署项目
  3. gradle -v不是外部命令, 内部命令,或批处理文件
  4. spring boot 定时任务
  5. node.js缓存处理方式
  6. 使用QQ第三方登录 并在父页面跳转刷新
  7. SpringBoot如何添加拦截器
  8. 常见的浏览器兼容性问题与解决方案——CSS篇
  9. linux 获取当前程序路径
  10. Java Collections Framework知识结构目录