javaScript高级教程(二)Scope Chain & Closure Example

  1 <!DOCTYPE html>
  2 <html>
  3      <head>
  4     <meta charset=gb2312 />
  5     <title>js</title>
  6     <script>
  7 //function语句在解析时会被提升,不管function语句放置在哪里,
  8 //它都会被移动到所在作用域的顶层。
  9 addEvent(window,'load',initAnchors);
 10 
 11 
 12  function initAnchors(){
 13     for(var i=1; i<=3; i++){
 14         var anchor = $('anchor'+i);        
 15         registerListener(anchor,i);  //函数中函数,也就是闭包,registerListener可以保存外部变量的值。
 16     }
 17  };
 18  /*
 19 把事件处理函数注册到一个独立的函数中。
 20 
 21 现在click事件处理函数的外部作用域变成了registerListener()函数。
 22 
 23 每次调用registerListener()函数时都会生成该函数的一个副本,
 24 以维护正确的变量作用域。
 25 */
 26  function registerListener(anchor,i){
 27    addEvent(anchor,'click',function(){
 28         alert('my id is anchor'+i);
 29     });
 30  }
 31 /*
 32 因为i的值实际上是单击事件发生时才从作用域链中取得。
 33 当单击事件必发生时,initAnchors()已经执行完毕(验证:在循环加入alert(i)后,打开网页会弹出三次框)。
 34 此时i=4。所以alert会显示相同信息。
 35 
 36 具体来说,当click事件处理函数被调用时,它会先在事件处理函数的内部作用域中查找i的值,
 37 但click事件的匿名处理函数中没有定义i的值,所以它再到其外部作用域(initAnchors()函数)中查找。
 38 而外部作用域中i=4。
 39 
 40  function initAnchors(){
 41     for(var i=1; i<=3; i++){        
 42         //alert(i);
 43         var anchor = $('anchor'+i);        
 44         addEvent(anchor,'click',function(){
 45             alert('my id is anchor'+i);
 46         });
 47     }
 48  };
 49 
 50 */
 51 function addEvent( node, type, listener ) {
 52     if (node.addEventListener) {
 53         // W3C method
 54         node.addEventListener( type, listener, false );
 55         return true;
 56     } else if(node.attachEvent) {
 57         // MSIE method
 58         //使用attachEvent()注册的回调函数没有Event参数,需要读取Window对象的event属性
 59         //使用attachEvent()作为全局函数调用。而不是事件发生其上的文档元素的方法来调用
 60         //也就是说attachEvent()注册的回调函数执行时,this指向window对象,而不是事件目标元素。
 61         //下面修正这些问题
 62         node['e'+type+listener] = listener;
 63         node[type+listener] = function(){
 64             node['e'+type+listener]( window.event );
 65         }
 66 
 67         //IE事件模型不支持事件捕获,所以需要两个参数
 68         node.attachEvent( 'on'+type, node[type+listener] ); 
 69         
 70          
 71         return true;
 72     }
 73     
 74     // Didn't have either so return false
 75     return false;
 76 };
 77 
 78 function $() {
 79     var elements = new Array();
 80     
 81     // Find all the elements supplied as arguments
 82     for (var i = 0; i < arguments.length; i++) {
 83         var element = arguments[i];
 84         
 85         // If the argument is a string assume it's an id
 86         if (typeof element == 'string') {
 87             element = document.getElementById(element);
 88         }
 89         
 90         // If only one argument was supplied, return the element immediately
 91         if (arguments.length == 1) {
 92             return element;
 93         }
 94         
 95         // Otherwise add it to the array
 96         elements.push(element);
 97     }
 98     
 99     // Return the array of multiple requested elements
100     return elements;
101 };
102     </script>                
103      </head>
104 
105      <body>
106        <ul>
107         <li><a href="#" id="anchor1">Anchor 1</a></li>
108         <li><a href="#" id="anchor2">Anchor 2</a></li>
109         <li><a href="#" id="anchor3">Anchor 3</a></li>
110       </ul>
111         
112      </body>
113 </html>
原文地址:https://www.cnblogs.com/yuyutianxia/p/3272699.html