引用类型---函数

在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。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值