zoukankan      html  css  js  c++  java
  • javaScript之function定义

    背景知识 

    函数定义 
    在javaScript中,function的定义有3种: 

    1、匿名定义 
                   function(){} 

    2、非匿名定义 
                   function fn(){} 
                   fn = new Function(); 


    触发函数执行 
    对于匿名函数: 
                           (function(){})();       //执行一个匿名函数 
                           var f = function(){}(); //执行一个匿名函数,并将匿名函数的返回值,赋值给f 
                           !function(){}();        //执行一个匿名函数 
                      
                  以上三种写法, 
                  无非就是要把 匿名函数 作为一个表达式块 然后执行。 


    对于非匿名函数: 
                           函数名();       //如: fn(); 


    用法示例 
    例子 1 
    function add(x, y){ 
       return(x + y);  

    例子 2 
    var add = new Function("x", "y", "return(x+y)"); 

    例子 3 
    var fn = function(){ }  
    将匿名函数的引用赋值给一个变量。(最常用的写法)如: 

    var add = function(x, y){ 
       return(x + y);  

    ---------------------------------------------------------------- 
    可以用如下代码行调用以上函数: 
    add(2, 3); 

    注意 : 在调用函数时,请确保包含了括号和必需的参数。调用函数时不用括号导致返回函数的文本而不是函数执行的结果。 
    add(2, 3);// return  "5" 
    add;      // renturn  " function add(x, y){return(x + y);} 




    1、用法剖析 

    Html代码  收藏代码
    1. <html>  
    2.         <head>  
    3.             <style type="text/css">  
    4.             p{  
    5.                 #CCCCCC;  
    6.                 height:20px;  
    7.                 100px;  
    8.                   
    9.               
    10.             }  
    11.             </style>  
    12.         </head>  
    13.     <body >  
    14.   
    15.         <p>test</p>  
    16.         <p>test</p>  
    17.         <p>test</p>  
    18.         <p>test</p>  
    19.         <p>test</p>  
    20.         <p>test</p>  
    21.   
    22.         <script type="text/javascript">  
    23.         /********************Method 1********************************/  
    24.         //常规的写法(正确的写法)  
    25.         /*  
    26.         var item=document.getElementsByTagName('p');  
    27.         for(var i=0;i<item.length;i++){  
    28.             item[i].onclick=(function(i){  
    29.                                 return function(){  
    30.                                            alert(i);  
    31.                                         }  
    32.                             })(i);  
    33.         }  
    34.   
    35.         */  
    36.         /********************Method 2********************************/  
    37.         //所有的 p 都 alert() 最后一个 i 的值(错误的写法)  
    38.         /*  
    39.         var item=document.getElementsByTagName('p');  
    40.         for(var i=0;i<item.length;i++){  
    41.             item[i].onclick=function(){  
    42.                 alert(i);  
    43.             };  
    44.         }  
    45.         */  
    46.           
    47.         /*  
    48.         说明:  
    49.         item[i].onclick=(function(){})(); 匿名函数与立即执行 ,然后把结果给item[i].onclick  
    50.         */  
    51.           
    52.         /********************Method 3********************************/  
    53.         //最能表达含义的写法(正确的写法)  
    54.         function createFunction(index){  
    55.             return function(){  
    56.                         alert(index);  
    57.                     }  
    58.         }  
    59.          
    60.         var elems = document.getElementsByTagName('p');  
    61.         for(var i=0,len=elems.length; i<len; i++){  
    62.             elems[i].onclick = createFunction(i);  
    63.         }  
    64.           
    65.           
    66.         /*说明:  
    67.         return function(){  
    68.                             alert(letter);  
    69.                         }  
    70.                           
    71.          =  
    72.            
    73.          return var fn = new Function(){  
    74.                             alert(letter);  
    75.                          }  
    76.                            
    77.            调用 function ,生成(定义)function.  
    78.            renturn 的 时候其实是 new 了一个function 出来。  
    79.      
    80.         */  
    81.   
    82.         </script>  
    83.     </body>  
    84. </html>  



    2、运行效果图 

     





    3、深入理解js的dom机制 


    js的一切对象(包括函数)都是依赖于 html的dom而存在的。 

    默认对象是window,所有的方法、属性,默认都是window对象的属性和方法 
    --------------------------- 
    alert() = window.alert() 
    --------------------------- 
    var x = window.x 
    var x = 10; 
    alert(window.x ); //10 

    我们猜测所有js函数运行时的环境,也是基于某个对象的(该对象的属性就是其运行环境)。 

    请看下面的例子: 

    例子一 

    Html代码  收藏代码
    1. <html>  
    2.     <head>  
    3.         <style type="text/css">  
    4.         p{  
    5.             200px;  
    6.             height:30px;  
    7.               
    8.         }  
    9.         </style>  
    10.     </head>  
    11.     <body>  
    12.         <p>test </p>  
    13.         <p>test </p>  
    14.         <p>test </p>  
    15.         <p>test </p>  
    16.         <p>test </p>  
    17.         <p>test </p>  
    18.         <script type="text/javascript">  
    19.         window.onload=function(){  
    20.             var adiv=document.getElementsByTagName('p');  
    21.             for(var i=0;i<adiv.length;i++){  
    22.                 adiv[i].onclick=function(){  
    23.                     alert(i);  
    24.                 }  
    25.             }  
    26.         }  
    27.         </script>  
    28.     </body>  
    29. </html>  


    结果:(无论点那个都alert 6) 

     




    例子二 

    Html代码  收藏代码
    1. <html>  
    2.     <head>  
    3.         <style type="text/css">  
    4.         p{  
    5.             200px;  
    6.             height:30px;  
    7.               
    8.         }  
    9.         </style>  
    10.     </head>  
    11.     <body>  
    12.         <p>test </p>  
    13.         <p>test </p>  
    14.         <p>test </p>  
    15.         <p>test </p>  
    16.         <p>test </p>  
    17.         <p>test </p>  
    18.         <script type="text/javascript">  
    19.         window.onload=function(){  
    20.             var adiv=document.getElementsByTagName('p');  
    21.             for(var i=0;i<adiv.length;i++){  
    22.                 adiv[i].onclick=(function(i){  
    23.                     return function(){ alert(i);};  
    24.                 })(i);  
    25.             }  
    26.         }  
    27.         </script>  
    28.     </body>  
    29. </html>  


    结果:(正常) 

     




    原因: 

    在例子二中, 
    改变了onclick事件的function的作用域范围。 
    (function(){ 
        return fuction(){}; 
    })(); 
    新new了一个function作用域,赋值给onclick事件。 



    分析: 



    例子一: 
    当onclick触发时,它实际(引用)运行的环境是 window.onload , 
    window.onload是一个function,而它又有自己的属性: 
    window.onload.adiv 
    window.onload.i 
    window.onload.adiv[0].onclick 
    window.onload.adiv[1].onclick 
    window.onload.adiv[2].onclick 
    window.onload.adiv[3].onclick 
    ... 

    onclick 会在当前作用域中找adiv(找到了) ,也会去找 i ,但是此时 i 的值 是 adiv.leng-1 
    所以会一直 alert 一个值 



    而如下方式(例子二): 
    window.onload=function(){ 
        var adiv=document.getElementsByTagName('p'); 
        for(i=0;i<adiv.length;i++){ 
            adiv[i].onclick=(function(i){ 
                return function(){alert(i)}; 
            })(i); 
            } 
        } 

    是采用匿名函数立即执行,利用立即执行为匿名函数,window.onload为自身创建属性(一个匿名函数) 
    此匿名又有2个属性(一个参数i,一个funcion) 
    并把执行后的结果赋值给 adiv[i].onclick 
    此时window.onload的结构大致是: 
    window.onload.adiv 
    window.onload.i 
    window.onload.adiv[0].onclick 
    window.onload.(function(0){}) 
    window.onload.(function(0){}).i 
    window.onload.(function(0){}).function 

    window.onload.adiv[1].onclick 
    window.onload.(function(1){}) 
    window.onload.(function(1){}).i 
    window.onload.(function(1){}).function 

    ... 

    赋值后 
    window.onload.adiv[0].onclick = 
    window.onload.(function(0){}).function 

    此时adiv[0].onclick的作用域是:window.onload.(function(0){}) 
                     不再是原来的:window.onload 

                     
    在新的作用域中是有 i 的,而 i 的值,就是当初传进来的值。 
                 



    再看下面的例子: 

    Html代码  收藏代码
    1. <html>  
    2.     <head>  
    3.         <style type="text/css"></style>  
    4.     </head>  
    5.     <body>  
    6.         <script type="text/javascript">  
    7.         /*  
    8.         //1.  
    9.         function Wen(){  
    10.             this.name = "taobao";  
    11.             this.waitMes=function(){  
    12.                 setTimeout(function(){this.fn(this.name);},1000);                   
    13.             };  
    14.             this.fn=function(name){  
    15.                 alert(name);  
    16.             }  
    17.         }  
    18.         var foo=new Wen();  
    19.         foo.waitMes();  
    20.           
    21.         //**运行结果:空。  
    22.         // *因为setTimeout 运行时的上下文环境是window  
    23.         // *而 window 没有 fn 和 name 属性  
    24.         //**故alert值为空  
    25.           
    26.         //2.  
    27.         var name = "taobao";         
    28.         function fn (name){  
    29.             alert(name);  
    30.         }         
    31.         function Wen(){  
    32.             this.waitMes=function(){  
    33.                 setTimeout(function(){this.fn(this.name);},1000);   
    34.             };  
    35.         }  
    36.         var foo=new Wen();  
    37.         foo.waitMes();  
    38.           
    39.         //**运行结果:非空。         
    40.         // *将 fn 和 name 放在 window 对象下  
    41.           
    42.           
    43.         //3.  
    44.         function Wen(){  
    45.             this.name = "taobao";  
    46.             this.waitMes=function(){  
    47.                 var that = this;  
    48.                 setTimeout(function(){that.fn(that.name);},1000);   
    49.             };  
    50.             this.fn=function(name){  
    51.                 alert(name);  
    52.             }  
    53.         }  
    54.         var foo=new Wen();  
    55.         foo.waitMes();  
    56.           
    57.         //**运行结果:非空。         
    58.         // *that作为参数传递到this中  
    59.         */  
    60.           
    61.        //4.   
    62.        function Wen(){  
    63.             this.name = "taobao";  
    64.             this.waitMes=function(){  
    65.                 var that = this;  
    66.                 setTimeout(that.fn,1000);   
    67.             };  
    68.             this.fn=function(){                 
    69.                 alert(this.name);  
    70.             };  
    71.              
    72.         }  
    73.         var foo=new Wen();  
    74.         foo.waitMes();  
    75.           
    76.         //**运行结果:非空。         
    77.         // *that作为参数传递到this中  
    78.           
    79.              
    80.         </script>  
    81.     </body>  
    82. </html>  


                 

                 

    4、变量作用域之 变量覆盖 

    原理: 
    由于js function对象的 hoisting 特性(函数内的所有变量都相当于自动在函数头部声明,赋值部分位置不变), 
    可能会导致访问变量时出现 undefined。 

    例子: 

    Javascript代码  收藏代码
    1.  <script type="text/javascript">  
    2.             //1.  
    3.             var foo = 'This is foo.';  
    4.             (function(){  
    5.                alert(foo);//This is foo.  
    6.             })();  
    7.               
    8.             //2.  
    9.             var foo = 'This is foo.';  
    10.             (function(){  
    11.                alert(foo);//undefined  
    12.                var foo = 2;  
    13.             })();  
    14.               
    15.             /** 
    16.             function对象的 hoisting 特性:函数内的所有变量都相当于自动在函数头部声明 
    17.             故 2 等价于这种写法: 
    18.              
    19.             var foo = 'This is foo.'; 
    20.             (function(){ 
    21.                var foo; 
    22.                alert(foo); 
    23.                foo = 2; 
    24.             })(); 
    25.             
    26.             在2中,又定义了一个局部变量foo,(覆盖了上级范围的foo),但是没有给赋初值, 
    27.             故访问foo时,出现 undefined 提示。 
    28.             */  
    29. </script>  



    所以,在函数定义时,其所有用到的变量,要写在函数体前。 








    补录: 
    --- 
    匿名函数自动执行,只是一种简便的写法而已,并无新奇或创意。 
    (function(){})(); 
    等价于 
    var fn = function(){}; 
    fn();//执行 
    在任何使用过程中,完全可以用后一种方式替代。 

  • 相关阅读:
    Bzoj 4408: [Fjoi 2016]神秘数 可持久化线段树,神题
    Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序
    Bzoj 1984: 月下“毛景树” 树链剖分
    面试题14:调整数组顺序使奇数位于偶数前面
    面试题13:在O(1)时间删除链表结点
    面试题12:打印1到最大的n位数
    面试题11:数值的整数次方
    面试题10:二进制中1的个数
    [找程序员代写推荐]不要说你工作多久,多厉害!这些题不从网上找答案,你能做出来吗???
    [原]Android开发技巧--ListView
  • 原文地址:https://www.cnblogs.com/xiaochao12345/p/3816452.html
Copyright © 2011-2022 走看看