javascript 基础 Function类型

函数--可以说是ECMAScript中最有意思的部分了。

函数实际上是对象,每个函数都是Function类型的实例。函数名实际上是一个指向函数对象的指针。

除了我们常见的两种函数声明方式,函数声明与函数表达式,还有一种使用Function构造函数创建,

例:

//Function构造函数方式
var sum = new Function("num1","num2","return num1+num2");

alert(sum(1,3));

解释:函数是对象,函数名是指针。

function sum(num1.num2){
 return num1 + num2;
}
alert(sum(10,20)); // 30

var anotherSum = sum; // 指向同一函数
alert(anotherSum(10,20)); // 30

sum = null; // sum引用指针为空,断绝于函数的关系,此时anotherSum指向的仍为那个函数
alert(anotherSum(10,20)); // 30 anotherSum指针指向的是真实对象,跟sum无关

注:使用不带圆括号的函数名访问的函数指针,而非调用函数;

1-2 函数重载

从语言角度讲,javascript不支持函数重载,不能够define相同的函数名然后编译器识别不同的参数执行不同的函数体。

但javascript可以通过自身属性模拟函数重载。

最基本函数重载,例:

function addSomeNumber(num1,num2,num3){
// 根据函数参数个数判断,实现函数重载   
        if(arguments.length==1){
            return arguments[0];    
        }
        if(arguments.length==2){
            return arguments[0]+arguments[1];    
        }
        if(arguments.length==3){
            return arguments[0]+arguments[1]+arguments[2];    
        }
        
}
function myInfo(name, password, email){
        //根据函数参数类型判断,实现函数重载
        if(typeof(email) != "undefined"){
            alert("填写信息正确");    
        }else if(typeof(password) != "undefined"){
            alert("email地址没有填写");
        }else {
            alert("密码不能为空");
        }
}

这种方法实现要领:将必须的参数放前面,将可以省略的参数放后面,未传入的参数类型是undefined.

1-3 作为值的函数

javascript中函数名就是变量,不仅可以把函数作为参数传递,也可将一函数作为另一个函数的结果返回,即return一个函数.

函数作为参数传递,例:

 

View Code
 1 function callSomeFunction(someFunction, someArgument){
 2     //someFunction参数传递函数,注意不要加(),这里传递的是函数引用
 3     return someFunction(someArgument);
 4 }
 5 function add10(num){
 6     return num+10;    
 7 }
 8 
 9 var result1 = callSomeFunction(add10, 20);
10 alert(result1); // 30
11 
12 function getGreeting(name){
13     return "hello "+name;
14 }
15 
16 var result2 = callSomeFunction(getGreeting,"han");
17 alert(result2);

 

在一函数中返回函数,例:

View Code
 1 /** 函数作为另一函数返回值 **/
 2 function createComparisonFunction(propertyName){
 3     // 返回函数
 4     return function(obj1, obj2)    {
 5         var value1 = obj1[propertyName];
 6         var value2 = obj2[propertyName];
 7         
 8         if(value1 < value2){
 9             return -1;    
10         }else if(value1 > value2){
11             return 1    
12         }else{
13             return 0;
14         }    
15     }
16 }
17 var data = [{name: "han",age: 22},{name: "Nicholas", age: 28}];
18 data.sort(createComparisonFunction("name"));
19 alert(data[0].name);
20 data.sort(createComparisonFunction("age"));
21 alert(data[0].age);

1-4 函数内部属性

两个特殊属性arguments和this,相信写过javascript代码的对这两个都不陌生。

arguments是一个类数组对象,包含传入的所有参数,arguments对象还有一个callee的属性,该属性是个指针,指向拥有这个arguments对象的函数,即(原函数).

例:

function factorial(num){
        if(num<=1){
            return 1;
        }else{
            return num*arguments.callee(num-1);
        }    
    }
alert(factorial(5));

对象this,与java中的this类似,this引用的是函数据以执行操作的对象。

View Code
 1 window.color = "red";
 2 var o ={ color:"blue"};
 3     
 4 
 5 function sayColor(){
 6     alert(this.color);
 7 }
 8 
 9 sayColor(); // "red"
10 o.sayColor = sayColor;
11 o.sayColor(); // "blue"

请牢记:函数的名字仅仅是一个包含指针的变量而已,即使在不同的环境中执行,全局的sayColor()与o.sayColor()调用的仍是同一个函数。

1-5 函数属性和方法

1,每个函数都含有两个属性:lengthprototype

length属性表示函数希望接收的参数

2,prototype是最值得深究的属性,prototype是保存它们所有实例方法的真正所在。诸如toString()和valueOf()都在prototype名下。

3,非继承的方法apply()和call(),apply和call第一个参数都是传入作用域,第二个参数apply需要传入参数数组,call是一个个参数传入

他们的使用实例,

View Code
 1 function sum(num1,num2){
 2     return num1+num2;    
 3 }
 4 // apply方法,参数按数组传入
 5 function callSum1(num1, num2){
 6     return sum.apply(this, arguments);
 7 }
 8 function callSum2(num1, num2){
 9     return sum.apply(this,[num1,num2]);
10 }    
11 alert(callSum1(10,10)); //20
12 alert(callSum2(10,10)); //20
13 
14 //call方法,参数一个个传入
15 function callSum3(num1, num2){
16     return sum.call(this,num1,num2);    
17 }
18 alert(callSum3(10,10)); //20

apply和call的最大作用还在于扩充函数赖以运行的作用域,对象不需要与方法有任何耦合关系。例:

View Code
 1 //最大的作用,扩充函数赖以运行的作用域
 2 window.color = "red";
 3 var o = {color: "blue"};
 4 
 5 function sayColor(){
 6     alert(this.color);
 7 }
 8 
 9 sayColor(); //red
10 sayColor.call(this); // red
11 sayColor.call(window); // red
12 sayColor.call(o); // blue
13 //最后这个,不需要在对象o里传入sayColor方法了,可以直接通过window对象中的sayColor方法调用了

 

4,继承的toLocaleString()和toString()方法始终返回函数的代码

2 高级函数重载

由于现在能力有限,高级函数重载后续再写

posted @ 2012-06-20 15:30  zzu-han  阅读(189)  评论(0编辑  收藏  举报