作用域链

三:作用域链

先来看一段代码:

 

[javascript] view plain copy
 
  1. name="lwy";  
  2. function t(){  
  3.     var name="tlwy";  
  4.     function s(){  
  5.         var name="slwy";  
  6.         console.log(name);  
  7.     }  
  8.     function ss(){  
  9.         console.log(name);  
  10.     }  
  11.     s();  
  12.     ss();  
  13. }  
  14. t();  


当执行s时,将创建函数s的执行环境(调用对象),并将该对象置于链表开头,然后将函数t的调用对象链接在之后,最后是全局对象。然后从链表开头寻找变量name,很明显

 

name是"slwy"。

但执行ss()时,作用域链是: ss()->t()->window,所以name是”tlwy"

下面看一个很容易犯错的例子:

 

[html] view plain copy
 
  1. <html>  
  2. <head>  
  3. <script type="text/javascript">  
  4. function buttonInit(){  
  5.     for(var i=1;i<4;i++){  
  6.         var b=document.getElementById("button"+i);  
  7.         b.addEventListener("click",function(){ alert("Button"+i);},false);  
  8.     }  
  9. }  
  10. window.onload=buttonInit;  
  11. </script>  
  12. </head>  
  13. <body>  
  14. <button id="button1">Button1</button>  
  15. <button id="button2">Button2</button>  
  16. <button id="button3">Button3</button>  
  17. </body>  
  18. </html>  

当文档加载完毕,给几个按钮注册点击事件,当我们点击按钮时,会弹出什么提示框呢?

 

很容易犯错,对是的,三个按钮都是弹出:"Button4",你答对了吗?

当注册事件结束后,i的值为4,当点击按钮时,事件函数即function(){ alert("Button"+i);}这个匿名函数中没有i,根据作用域链,所以到buttonInit函数中找,此时i的值为4,

所以弹出”button4“。

 

四:with语句

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

看下面代码

[javascript] view plain copy
 
  1. person={name:"yhb",age:22,height:175,wife:{name:"lwy",age:21}};  
  2. with(person.wife){  
  3.     console.log(name);  
  4. }  

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

 

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

posted @ 2016-08-18 15:57  G-Beniot  阅读(139)  评论(0编辑  收藏  举报