1.变量作用域
1)概念:程序代码中定义这个变量的区域。变量仅在自己的作用域及自己作用域包含的作用域下可见,除此之外,其他地方是不可见的。2)变量作用域分为两类:全局作用域(全局变量)和局部作用域(局部变量)
a.全局变量的作用域称为全局作用域
<span style="font-family:Microsoft YaHei;font-size:14px;"><span style="white-space:pre"> </span>var x = "global"; //全局变量,x对函数foo是可见
function foo(){
console.log(x); //打印出global
}
foo();
console.log(x);//打印出global</span>
b.局部变量的作用域称为局部作用域
<span style="font-family:Microsoft YaHei;font-size:14px;"><span style="white-space:pre"> </span>function foo(){
var x = "local";//局部变量,仅在函数foo内可见
console.log(x); //打印出local
}
foo();
console.log(x); //error:x is not defined;x变量是局部变量,foo函数外不可见</span>
2.函数作用域
概念:变量在声明它们的函数体以及这个函数体嵌套的任意函数体内都是有定义的。即函数内声明的变量在函数体内始终是可见的。注意:JavaScript是没有块级作用域的;函数作用域在函数定义的时候就确定的,而不是调用时才生成的。
例子说明:
例子1:
<span style="white-space:pre"> </span>var x ="global";//全局变量
function foo(){
<span style="font-family: Arial, Helvetica, sans-serif;">//在此处你可能误以为会打印出global,其实不然,因为数内声明的变量在函数体内始终是可见的,所以此处输出局部变量x,局部变量的声明会提前,但赋值操作还<span style="white-space:pre"> </span>没执行,即输出undefined </span><pre name="code" class="javascript"> <span style="white-space:pre"> </span> console.log(x);
var x = "local";//局部变量 function a(){ console.log(x);//打印出local } a(); console.log(x);//打印出local}foo();
例子2:
<span style="white-space:pre"> </span>function foo(){
for(var i = 0;i < 5;i++){
}
//你可能误以为会打印出error:x is not defined;但结果是打印出5,这是因为在JavaScript里面是没有块级作用域的,只有函数作用域,所以,在函数<span style="white-space:pre"> </span> 内定义的变量在函数体内始终是可见的
console.log(i);
}
foo();
3.作用域链
每一段JavaScript代码(全局代码或者函数)都有与之关联的作用域链。作用域链是一个对象列表或者链表。作用域链的组成:A函数的作用域 ---> A的父函数的作用域 ---> A的父父函数的作用域 ---> ... ---> 全局作用域(不包含在任何函数定义内的代码)
当JavaScript需要查找变量x的值得时候的解析过程:
它会从链中的第一个对象开始找,如果这个对象存在变量x,则使用该对象的变量x,解析结束;否则,就会继续查找下一个对象,以此类推。如果该作用域链上不存在变量x,则最终会抛出一个异常。
例子:
var x = 1;
function a(){
function b(){
function c(){
console.log(x);
}
d();
}
b();
}
a();
解析过程:执行console.log(x)这个语句的时候,它会先在c函数的函数作用域查找x,x不存在;它继续在b函数的函数作用域中查找,看看x存不存在,x不存在;它继续在a函数的函数作用域中查找,看看x存不存在,x不存在;它会继续在最外层作用域(全局作用域)寻找x,存在变量x,即打印出1。