Js变量作用域及作用域链

要理解变量的作用域范围就得先理解作用域链 
用var关键字声明一个变量时,就是为该变量所在的对象添加了一个属性。 

作用域链:由于js的变量都是对象的属性,而该对象可能又是其它对象的属性,而所有的对象都是window对象的属性,所以这些对象的关系可以看作是一条链 
链头就是变量所处的对象,链尾就是window对象

看下面的代码:

function t() { 
    var a; 
    function t2() { 
        var b; 
    } 
}

js中函数也是对象,所以变量a所在的对象是t,t又在window对象中,所以a的作用域链如下 
t--window 
那么b所以在的对象即t2,t2又包含在t中,t又在window对象,所以b的作用域链如下 
t2--t--window 
明白了作用域链下面就开始变量的作用域分析了

1 javascript 没有var的变量都为全局变量,且为window对象的属性

function test1() { 
all = 30;   //此为全局变量
alert(all);   //30
} 

test1();  //30

alert(all);   //30
alert(window.all);  //30

 2 函数内(函数内的函数除外)定义的变量在整个函数内部都有效

function test2() { 
  var t = 0; 
  //在for的条件里定义变量,这个变更的作用域链对象是这个函数 
  //因此在整个的函数里它是有效的 
  for (var i = 0; i < 5; i++) { 
    t += i; 
  } 
  alert(i); 
} 
test2();

3 函数内部的变量取代全局同名变量

var t = "bb"; 
function test() { 
//执行t的时候,它会先找作用域链对象,由于它定义在函数内部,所以这个函数就是它的作用域链的第一个对象 
//而在这个对象里又有t的定义,所以t就是局部变量了,它替换了全局变量t

//t只是此时有定义,但并没有赋值,赋值在下一行,所以这里输出了undefined 
alert(t); 
var t = "aa"; 
alert(t); //此时t已经被赋值,所以这里输出了aa
} 
test();

4 js没有块作用域

if (true) { 
  //在块中定义了一个变量,它的作用域链的第一个对象就是全局对象window 
  var tmp = 0; 
} 
//tmp的作用域链的第一个对象就是全局对象window,而上面又有全局对象中相关的var语句,因此输出0 
alert(tmp); 

5 with语句

说到作用域链,不得不说with语句。with语句主要用来临时扩展作用域链,将语句中的对象添加到作用域的头部。

person={name:"yhb",age:22,height:175,wife:{name:"lwy",age:21}};  
with(person.wife){  
    console.log(name);  //此时的作用域是wife,所以name="lwy"
} 

with语句将person.wife添加到当前作用域链的头部,所以输出的就是:“lwy".

with语句结束后,作用域链恢复正常。

 

 

 

posted @ 2015-10-14 17:51  暗夜心慌方  阅读(178)  评论(0)    收藏  举报