代码改变世界

js笔记三:function类型

2012-04-04 23:10  折翼的鸟  阅读(243)  评论(0编辑  收藏  举报

  每个函数实际上是对象。每个函数都是function类型的实例,而且都与其他引用类型一样具有属性和方法,由于函数是对象,因此函数名实际也是一个指向函数对象的指针,不会与某个函数绑定。

    由于函数名字仅仅是一个指针,因此函数名与包含对象指针没有什么不同。换句话说一个函数可能会有多个名字,

  function sum(sum1,sum2){

return sum1 + sum2;

  }

  alert(sum(10,10))   //20

 

  var anothersum = sum;

  alert(anothersum(10,20))    ///30;

 

  sum = null;

  alert(anothersum(10,20))    ///30;

 

  1、函数没有重载

     如果声明两个同名的函数,而结果则是后面的函数覆盖了前面的函数。

 

  2、函数声明与函数表达式

     解析器在向执行环境中加载数据时,为函数声明和函数表达式并不一样,解析器会率先读取函数声明,并使其在执行任何代码之前调用,至于函数表达式,则必须等到解析器执行到它所在的代码行时,才会真正的被解析执行

      alert(sum(10,10));

      function sum(num1,num2){

        return num1 + num2;

      }

      以上代码完全可以正常运行,因为在代码开始执行之前,解析器就已经读取函数声明并将其添加到执行环境中了。

     

      alert(sum(10,10));

      var sum = function(num1,num2){

            return num1 + num2;

      }

      以上代码会在运行期间产生错误,因为在执行到函数所在语句之前,变量sum是不会保存有对函数的引用

   

   3、函数内部属性

        在函数内部有两个特殊对象:arguments和this  arguments他是一个类数组对象,包含着传入函数的所有参数,

        另一个this,this引用的是函数据以执行操作的对象,或者说this是函数在执行时所处的作用域(当在网页的全局调用函数时,this对象引用的就是window)

    window.color = 'red';

    var o = {color = 'blue'};

 

    function saycolor(){

      alert(this.colot);

    }

 

    saycolor(); //red

 

    o.saycolor = saycolor;

    o.saycolor();   //blue

 

    以上这个函数saycolor()是在全局作用域中定义的,它引用了this对象,由于在调用之前this的值并不确定,因此this可能会在代码执行过程引用不同的对象,当在全局作用域中调用saycolor()时,this引用的是全局对象window换句话说,对this.color求值会转换成window.color求值,于是结果就成了red,而当把这个函数赋值给对象o并调用了

o.saycolor()时,this引用的就是对象o,因此this.color求值会转换成o.color求值,结果就成了blue

    注意函数的名字仅仅是一个包含指针的变量而已,因此即使在不同的环境中执行,全局的saycolor()与    o.saycolor()指向的仍然是同一个函数

 

     4、函数属性和方法

    每个函数都有两个属性:length和prototype

   

    其中length属性表示函数希望接受的命名参数的个数。如:

    function sayName(name){

      alert(name);

    }

    alert(sayName.length)   //1

   

    每个函数都包含两个非继承而来的方法:apply()和call(),这两个方法的用途都是在特殊的作用域中调用函数,实际上等于设置函数体内的this对象的值。

    apply()方法接受两个参数:一个是在其中运行函数的作用域,另一个参数数组,其中第二个参数可以是Array的实例,也可以是arguments对象

   

    function sum(num1,num2){

       return num1 + num2;

    }

 

    function callSum1(num1,num2){

       return sum.apply(this,arguments);

    }

   

    function callSum2(num1,num2){

       return sum.apply(this,[num1,num2]);

    }

     

    alert(callSum1(10,10)); //20;

    alert(callSum2(10,10)); //20;

 

    在这个例子中,callSum1()在执行sum()函数时传入了this作为作用域(因为是在全局作用域中调用的,所以传入的就是window对象)和argments对象.而callSum2同样也调用了sum()函数,但它传入的则是this和一个参数数组,这两个函数都会正常执行并返回正确的结果

    call()方法和apply()方法的作用完全相同,区别仅在于接受的参数方式不同,传递给函数的参数必须逐个列举来.

    function sum(num1,num2){

       return num1 + num2;

    }

    function callSum1(num1,num2){

       return sum.call(this,num1,num2);

    }

 

    apply()和call()真正的用武之地,他们真正强大的地方就是能够扩充函数赖以运行的作用域.

    window.color = 'red';

    var o = {color : 'blue'};

 

    function saycolor(){

        alert(this.color);

    }

    saycolor(); //red;

 

    saycolor.call(this);    //red

    saycolor.call(window);  //red

    saycolor.call(o);   //blue  当运行这句话的时候,函数的执行环境就不一样了,因为此时的函数体内this对象以及指向了o