一、作用域
作用域就是变量和函数的可访问范围,控制着变量和函数的可见性与生命周期,在JavaScript中变量的作用域有全局作用域和局部作用域。
变量没有在函数内声明或者声明的时候没有带var就是全局变量,拥有全局作用域,window对象的所有属性拥有全局作用域;在代码任何地方都可以访问,函数内部声明并且以var修饰的变量就是局部变量,只能在函数体内使用,函数的参数虽然没有使用var但仍然是局部变量。
var a=3; //全局变量
function fn(b){ //局部变量
c=2; //全局变量
var d=5; //局部变量
function subFn(){
var e=d; //父函数的局部变量对子函数可见
for(var i=0;i<3;i++){
console.write(i);
}
alert(i);//3, 在for循环内声明,循环外function内仍然可见,没有块作用域
}
}
alert(c); //在function内声明但不带var修饰,仍然是全局变量
然而执行环境(execution context)定义了变量或函数有权访问的其它数据,决定了它们的各自行为。每个执行环境都有一个与之关联的变量对象(variable object, VO),执行环境中定义的所有变量和函数都会保存在这个对象中,解析器在处理数据的时候就会访问这个内部对象。
全局执行环境是最外层的一个执行环境,在web浏览器中全局执行环境是window对象,因此所有全局变量和函数都是作为window对象的属性和放大创建的。
二、作用域链
当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain,不简称sc)来保证对执行环境有权访问的变量和函数的有序访问。作用域第一个对象始终是当前执行代码所在环境的变量对象(VO)
function a(x,y){
var b=x+y;
return b;
}
在函数a创建的时候它的作用域链填入全局对象,全局对象中有所有全局变量
如果执行环境是函数,那么将其活动对象(activation object, AO)作为作用域链第一个对象,第二个对象是包含环境,下一个是包含环境的包含环境。。。。。
function a(x,y){
var b=x+y;
return b;
}
var tatal=a(5,10);
这时候 var total=a(5,10);语句的作用域链如下
在函数运行过程中标识符的解析是沿着作用域链一级一级搜索的过程,从第一个对象开始,逐级向后回溯,直到找到同名标识符为止,找到后不再继续遍历,找不到就报错。