`

javaScript之function定义

阅读更多
背景知识

变量类型与变量声明

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

//

// 1、匿名定义
               function(){}

// 2、非匿名定义
               function fn(){}

// 3、使用 Functon 对象定义
               fn = new Function("some code");

// 这里说明一下:
// function 是一个关键字,而 Function 是一个对象。



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



2、对于非匿名函数:
                       函数名();       //如: 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>
<head>
<style type="text/css">
p{ background-color: #ada; height:40px; width:300px;line-height:40px;border-radius:10px;padding:0 20px;}
#myDiv{margin:auto;width:400px;background-color:#fefefe;}
body{padding-top:20px;}
</style>
</head>
<body>
    <div id="myDiv">
        <p>test_0</p>
        <p>test_1</p>
        <p>test_2</p>
        <p>test_3</p>
        <p>test_4</p>
        <p>test_5</p>
    </div>
    
        <script type="text/javascript">
        
        /********************Method 1********************************/
        
        //常规的写法(正确的写法)
        function method_1(){
            var item=document.getElementsByTagName('p');
            for(var i=0;i<item.length;i++){
                item[i].onclick=(function(i){
                    return function(){
                      alert(i);
                    }
                })(i);
            }
        }
        

        
        /********************Method 2********************************/
        
        //所有的 p 都 alert() 最后一个 i 的值(错误的写法)
        function method_2(){
            var item=document.getElementsByTagName('p');
            for(var i=0;i<item.length;i++){
                item[i].onclick=function(){
                    alert(i);
                };
            }
        }
       /*
        说明:
        item[i].onclick=(function(){})(); 匿名函数与立即执行 ,然后把结果给item[i].onclick
        */
        
        
        /********************Method 3********************************/
        //最能表达含义的写法(正确的写法)
        function method_3(){
            function createFunction(index){
                return function(){
                            alert(index);
                        }
            }
           
            var elems = document.getElementsByTagName('p');
            for(var i=0,len=elems.length; i<len; i++){
                elems[i].onclick = createFunction(i);
            }
        }

        
        
        /*说明:
         *      return function(){ alert(letter); }
         *      =
         *      return var fn = new Function(){ alert(letter);}
         *   
         *      调用 function ,生成(定义)function.
         *      renturn 的 时候其实是 new 了一个function 出来。
         */
         
         //===================================================================================
         //run function.
         
         //window.onload = method_3;         
         //or
         window.onload = function(){
            method_1();
         }
         
        </script>
    </body>
</html>


注:关于 window.onload : Launching Code on Document Ready

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>
    <head>
        <style type="text/css">
        p{
            width:200px;
            height:30px;
            background-color:#F0F0F0;
        }
        </style>
    </head>
    <body>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <script type="text/javascript">
        window.onload=function(){
            var adiv=document.getElementsByTagName('p');
            for(var i=0;i<adiv.length;i++){
                adiv[i].onclick=function(){
                    alert(i);
                }
            }
        }
        </script>
    </body>
</html>

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






例子二
<html>
    <head>
        <style type="text/css">
        p{
            width:200px;
            height:30px;
            background-color:#F0F0F0;
        }
        </style>
    </head>
    <body>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <p>test </p>
        <script type="text/javascript">
        window.onload=function(){
            var adiv=document.getElementsByTagName('p');
            for(var i=0;i<adiv.length;i++){
                adiv[i].onclick=(function(i){
                    return function(){ alert(i);};
                })(i);
            }
        }
        </script>
    </body>
</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>
    <head>
        <style type="text/css"></style>
    </head>
    <body>
        <script type="text/javascript">
        /*
        //1.
        function Wen(){
            this.name = "taobao";
            this.waitMes=function(){
                setTimeout(function(){this.fn(this.name);},1000);                 
            };
            this.fn=function(name){
                alert(name);
            }
        }
        var foo=new Wen();
        foo.waitMes();
        
        //**运行结果:空。
        // *因为setTimeout 运行时的上下文环境是window
        // *而 window 没有 fn 和 name 属性
        //**故alert值为空
        
        //2.
        var name = "taobao";       
        function fn (name){
            alert(name);
        }       
        function Wen(){
            this.waitMes=function(){
                setTimeout(function(){this.fn(this.name);},1000); 
            };
        }
        var foo=new Wen();
        foo.waitMes();
        
        //**运行结果:非空。       
        // *将 fn 和 name 放在 window 对象下
        
        
        //3.
        function Wen(){
            this.name = "taobao";
            this.waitMes=function(){
                var that = this;
                setTimeout(function(){that.fn(that.name);},1000); 
            };
            this.fn=function(name){
                alert(name);
            }
        }
        var foo=new Wen();
        foo.waitMes();
        
        //**运行结果:非空。       
        // *that作为参数传递到this中
        */
        
       //4. 
       function Wen(){
            this.name = "taobao";
            this.waitMes=function(){
                var that = this;
                setTimeout(that.fn,1000); 
            };
            this.fn=function(){               
                alert(this.name);
            };
           
        }
        var foo=new Wen();
        foo.waitMes();
        
        //**运行结果:空。       
        // * this 仍然是指 window 对象。
        // * 因为调用的是 window 对象的 setTimeout()方法。
        // */
           
        </script>
    </body>
</html>

            

            

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

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

例子:
 <script type="text/javascript">
            //1.
            var foo = 'This is foo.';
            (function(){
               alert(foo);//This is foo.
            })();
            
            //2.
            var foo = 'This is foo.';
            (function(){
               alert(foo);//undefined
               var foo = 2;
            })();
            
            /**
            function对象的 hoisting 特性:函数内的所有变量都相当于自动在函数头部声明
            故 2 等价于这种写法:
            
            var foo = 'This is foo.';
            (function(){
               var foo;
               alert(foo);
               foo = 2;
            })();
           
            在2中,又定义了一个局部变量foo,(覆盖了上级范围的foo),但是没有给赋初值,
            故访问foo时,出现 undefined 提示。
            */
</script>


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








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




—————————————

javascript 函数基础系列文章

1、JavaScript之变量的作用域
2、javascript之变量类型与变量声明及函数变量的运行机制
3、javaScript之function定义
4、javascript之function的prototype对象
5、javascript之function的(closure)闭包特性
6、javascript之function的this   
7、javascript之function的apply(), call()



___________


javascript 面向对象编程系列文章:

    1、javaScript之面向对象编程
    2、javascript之面向对象编程之属性继承
    3、javascript之面向对象编程之原型继承 
   

-






-转载请注明出处:
http://lixh1986.iteye.com/blog/1947017



-
  • 大小: 8.2 KB
  • 大小: 8.8 KB
  • 大小: 8.7 KB
分享到:
评论
1 楼 guodongkai 2015-04-25  
谢谢您能将知识精华汇编总结,让初学者们从原理中学会和提高。

相关推荐

    JavaScript使用function定义对象并调用的方法

    主要介绍了JavaScript使用function定义对象并调用的方法,实例分析了javascript中function定义及使用对象与方法的相关技巧,需要的朋友可以参考下

    JavaScript 定义function的三种方式小结

    如: 代码如下: function func() { //body code } (3) 使用JavaScript内置Function对象构造。如: 代码如下: var func = new Function(“/*parameters*/”,”/*body code*/”); 声明变量定义与使用function表达式...

    JavaScript通过function定义对象并给对象添加toString()方法实例分析

    主要介绍了JavaScript通过function定义对象并给对象添加toString()方法,实例分析了javascript中function定义对象及添加方法的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下

    javascript两种function的定义介绍及区别说明

    javascript两种function的定义方式function a(){}和a=function(){}具体使用如下,感兴趣的朋友可以参考下,希望对你对你学习function的定义有所帮助

    Javascript 使用function定义构造函数

    Javascript并不像Java、C#等语言那样支持真正的类。但是在js中可以定义伪类。做到这一点的工具就是构造函数和原型对象。首先介绍js中的构造函数。

    JavaScript中的Function函数

    首先给大家介绍JavaScript中function定义函数的几种方法: 1.最基本的作为一个本本分分的函数声明使用。 复制代码 代码如下: function func(){} 或 复制代码 代码如下: var func=function(){}; 2.作为一个类构造...

    JavaScript中Function详解

    关键字function用来定义函数。...在JavaScript中,函数是Function类的具体实例。而且都与其它引用类型一样具有属性和方法。 函数名实际上是指向函数对象的指针,函数可以作为参数参与到传参和返回值中。 函数的

    JavaScript 中定义函数用 var foo = function () {} 和 function foo()区别介绍

    主要介绍了JavaScript 中定义函数用 var foo = function () {} 和 function foo()区别介绍,需要的朋友可以参考下

    JavaScript中Function函数与Object对象的关系

    注意:官方定义: 在Javascript中,每一个函数实际上都是一个函数对象. 我们先来看最简单的两个代码,也是最容易理解的. function fn(){} var obj = {} console.log(fn instanceof Function)//true conso

    JavaScript使用prototype定义对象类型

    From: JavaEye.com prototype提供了一套JavaScript面向对象基础设施,我们可以使用它来进行面向对象编程,定义对象类型方式如下: var Person = Class.create(); Person.prototype = { initialize : ...

    JavaScript程序设计课件:函数的定义方式.pptx

    JavaScript程序设计 函数的定义方式 5.2.1 函数的定义方式 概念 函数:用于封装一段完成特定功能的代码。...关键字function。 函数名。 参数。 函数体。 除了使用内置函数外,JavaScript中还可以根据具体情况自定义

    JavaScript 函数的定义-调用、注意事项

    函数定义 函数语句定义 function(a,b){ return a+b; } 表达式定义 var add = function(a,b){return a+b}; //函数表达式可以包含名称,这在递归时很有用 var f = function fact(x){ if(x&lt;=1) {return 1; }else ...

    JavaScript面向对象

    在JavaScript中定义JavaScript对象有两种方式: 方式一: var Book ={ getBookName:function(){ alert&#40;"获取书的名称"&#41; ; } }; 方式二 var oBook = function(){}; oBook.getBookName=...

    JavaScript中定义类的方式详解

    本文实例讲述了JavaScript中定义类的方式。分享给大家供大家参考,具体如下: ...在Javascript中,我们用function来定义类,如下: function Shape() { var x = 1 ; var y = 2 ; } 你或许会说,疑?这个不是定义

    JavaScript JMap类定义与使用方法示例

    在JavaScript中我们利用function类定义类 在类的内部我们用var 定义私有变量 私有函数 在类的内部我们用this 定义公有变量 (1)定义一个类 function JMap() { var arr={};//空类 //增加 this.put=function (key,...

    【JavaScript源代码】Javascript中异步等待的深入理解.docx

    Javascript中异步等待的深入理解  在本文中,我们将探讨async/await对于每个Javascript开发人员来说,异步编程的首选工具。... // async function always returns a promise async function greet() { 

Global site tag (gtag.js) - Google Analytics