Javascript對象arguments和this

函數內部有兩個特殊的對象:arguments和this。其中arguments是一個數組類對象,包含傳入函數的所有參數。雖然arguments的主要用途是保存函數參數,但是這個對象還有一個名叫callee的屬性,該屬性是一個指針,指向擁有這個arguments對象的函數,對比如下兩個階乘函數:

function fun1(){
   if (num<=1){
         return 1;
    }
    else{
      return num*fun1(num-1) 
   }
}
function fun2(){
   if (num<=1){
         return 1;
    }
    else{
      return num*arguments.callee(num-1) 
   }
}
        定義階乘函數一般要用到遞歸算法,在有函數名的時候,在函數內部可以調用函數名fun1,因此這個函數的執行將和函數名緊緊的耦合在一起。函數fun2的用法正好消除了這種耦合現象,函數體內再也沒有用到函數名,因此不論引用函數的時候引用什麼名字,都可以保證完成遞歸調用。例如:
var newfun=fun2;
 fun2=function(){
   return 0;
};
alert(newfun(5));    //120
alert(fun2(5));    //0
       因此,變量newfun獲得了fun2的函數值,實際上是在另一個位置保存了一個函數的指針,然後我們將0返回給變量fun2,如果像原來的fun1那樣不使用arguments.callee,函數調用之後就會返回0。可是,在解除了函數體內的代碼與函數名的耦合狀態之後,newfun()仍然能正常進行階乘的計算。而fun2(),如今特只能返回0.

      另一個函數內部的特殊對象是this,this引用的是函數據以執行操作的對象,或者說,this是函數在執行時所處的作用域(當在網頁的全局作用時,this對象引用的是window),看例子:

window.color="red";
var o={color:"blue"};
function sayColor(){
   alert(this.color);
}
sayColor();    //"red"
o.sayColor=sayColor;
o.sayColor();     //"blue"
     這個函數中sayColor()是在全局作用域中定義的,它引用了this對象,由於在調用函數前,this的值並不確定,因此this可能是會在代碼執行的時候引用不同的對象。當在全局作用域中調用sayColor時,this引用的是window,於是結果返回”red“。然而,當把這個函數賦給對象o,並調用o.sayColor()時,this引用的對象是o,因此對this.color求值會轉換成對o.color的求值,結果就返回了“blue”。

注意:函數的名字僅僅是一個包含指針的變量而已,因此,即使是在不同的環境中執行,全局的sayColor()函數與o.sayColor()指向的仍然是同一個函數。




   

    








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章