引用类型---函数

来源:互联网 发布:js解析json方式 编辑:程序博客网 时间:2024/06/15 22:46
在ECMAScript中,Function(函数)类型实际上是对象。每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,因此函数名实际上也是一个指向函数对象的指针。

一.函数的声明方式

1.普通的函数声明

function sum(num1,num2){        return num1+num2;    }

2.使用变量初始化函数

var sum = function(num1,num2){        return num1+num2;    }

3.使用Function构造函数

var box= new Function('num1', 'num2' ,'return num1 + num2');PS:第三种方式我们不推荐,因为这种语法会导致解析两次代码(第一次解析常规ECMAScript代码,第二次是解析传入构造函数中的字符串),从而影响性能。但我们可以通过这种语法来理解"函数是对象,函数名是指针"的概念。函数名仅仅是指向函数的指针,因此函数名和包含对象指针的其他变量一样。也就是说,不同的函数名可以指向同一个函数。
function hcd(a,b){            return a+b;        }        alert(hcd(1,2));                    //3        var h = hcd;                        //注意:不带括号的函数名表示的是访问函数指针,不是调用函数        alert(h(3,2));                      //5,因为复制的是指针,其实指向的是同一个函数        hcd = null;                         //表示hcd就和函数断绝关系了,他就不是函数指针了        alert(hcd(0,1))                     //hcd is not a function
首先定义了一个函数hcd,将h设置为与hcd相等,(注意:使用不带圆括号的函数名是访问函数指针,而非调用函数结果),这时hcd和h就指向同一个函数。因为函数的根源是对象,所以将hcd设置为空对象null,就可以将hcd和函数“断绝关系”。但是这并不影响h指向函数。

二.函数的特点

1. 没有重载

    function h(a){        return a+1;    }    function h(b){        return b+2;    }    alert(h(2));//4    其实和这个是一样的:    var h = function(a){        return a+1;    }    h = function(b){        return b+2;    }    alert(h(2));//4

2. 函数声明和函数表达式

函数声明:    解析器会先读取函数声明,并使其在执行任何代码前可用。    alert(hcd(1,2));//3    function hcd(a,b){        return a+b;    }    只是因为在解析时将函数声明放在了代码的顶部函数表达式:    是按代码的顺序执行的。    alert(hcd(1,2));    var hcd = function(a,b){        return a+b;    }    这是会报错误hcd is not a function;除了这点差别外,其他是一样的。

3.作为值的函数

    var hcd = function(a){            return a+5;        }        function h(b,c){            return b(c);        }        alert(h(hcd,10));//15        h函数接受两个参数,第一个参数为函数,第二个参数为传递给改函数的一个值。
一个数组,含有多个对象,根据对象的某一属性值的大小,对对象进行排序        var data =[            {                name:"a",                age:10            },            {                name:"b",                age:11            },            {                name:"v",                age:20            },            {                name:"g",                age:8            }        ]        function compare(s){            return function hcd(obj1,obj2){                var value1 = obj1[s];                var value2 = obj2[s];                if(value1<value2){                    return -1;                }else if(value1>value2){                    return 1;                }else{                    return 0;                }            }        }        data.sort(compare("age"))        console.log(data[0].age)//8        console.log(data[1].age)//10        console.log(data[2].age)//11        console.log(data[3].age)//20

4.函数内部的属性

  在函数的内部有两个特殊的对象:arguments和this

arguments

  arguments:类数组对象,包含所有传入函数中的参数。argument的callee属性指向该函数。
  例如:      常见的递归函数      function hcd(a){            if(a<=1){                return 1;            }else{                return a*hcd(a-1)            }        }      console.log(hcd(4))//24      这样的话就会将执行函数紧紧的与hcd耦合在一起。
 下面的方法会更好。      function hcd(a){            if(a<=1){                return 1;            }else{                return a*arguments.callee(a-1)            }        }        console.log(hcd(4))//24        这样一来:        var text = hcd;        hcd = function(){         return 0;        }         console.log(text(4))//24        console.log(hcd(24))//0        变量text获取了hcd的值,其实是在两外一个位置上保存了函数的指针。

this:

    this引用的是当前函数执行的环境对象。
    wndow.color = "red";        var o = {            color:"blue"        };        function say(){            console.log(this.color)        }        say();                      //"red"        o.say = say;        o.say();                     //"blue"
  say函数为在全局定义的函数,在调用函数前,并不能确定this是那个对象。  当在全局中调用时,this引用的是全局对象window,换句话说this.color会转换为window.color。  而当将say函数赋值给o.say()时,this引用的是对象o。

5.函数的属性和方法

    函数就是对象,所以有属性和方法。    每个函数都有两个属性:length,prototype

length

    length:接受参数的个数
        function hcd(a,b){            return a+b;        }        function h(a){            return a;        }        alert(hcd.length);                  //2        alert(h.length);                    //1

prototype

    对于prototype属性,它是保存所有实例方法的真正所在,也就是原型。这个属性,我们将在面向对象一章详细介绍。而prototype下有两个方法:apply()和call()每个函数都有2个非继承而来的方法call和apply,这两个方法可以让函数在特定的作用域中调用函数,其实等于设置this。

apply

    apply:参数1.运行函数的作用域,参数2.数组,也可以是数组实例,也可以是arguments
        function hcd(a,b){            return a+b;        }        function h1(c,d){            return hcd.apply(this,arguments);        }        function h2(c,d){            return hcd.apply(this,[c,d]);        }        alert(h1(10,10));        alert(h2(10,10));        在全局环境下调用h2和h1,所以传入hcd的this即为window对象

call:

    和apply的用法类似,只不过参数2不为数组
        function h2(c,d){            return hcd.call(this,c,d);        }        apply和call的真正强大在于扩充函数赖以运行的作用域。        window.color = "red";        var o = {            color:"blue"        };        function hcd(){            alert(this.color)        }        //在全局环境下运行        hcd();             //"red"        //在函数调用的环境下运行        hcd.call(this);     //"red"        //在全局环境下运行        hcd.call(window);     //"red"        //在o环境下运行        hcd.call(o);     //"blue"

bind()

创建一个函数的实例,this会绑定到传给bind()函数的值。
        window.color = "red";        var o = {            color:"blue"        };        function hcd(){            alert(this.color)        }        var objectSay = hcd.bind(o);        objectSay()//"blue"        hcd()调用bind()并传入对象o,意思就说在环境变量为o的情况下,创建一个函数实例objectSay。
原创粉丝点击