函數內部有兩個特殊的對象:arguments和this。其中arguments是一個數組類對象,包含傳入函數的所有參數。雖然arguments的主要用途是保存函數參數,但是這個對象還有一個名叫callee的屬性,該屬性是一個指針,指向擁有這個arguments對象的函數,對比如下兩個階乘函數:
function fun1(){ if (num<=1){ return 1; } else{ return num*fun1(num-1) } }
定義階乘函數一般要用到遞歸算法,在有函數名的時候,在函數內部可以調用函數名fun1,因此這個函數的執行將和函數名緊緊的耦合在一起。函數fun2的用法正好消除了這種耦合現象,函數體內再也沒有用到函數名,因此不論引用函數的時候引用什麼名字,都可以保證完成遞歸調用。例如:function fun2(){ if (num<=1){ return 1; } else{ return num*arguments.callee(num-1) } }
因此,變量newfun獲得了fun2的函數值,實際上是在另一個位置保存了一個函數的指針,然後我們將0返回給變量fun2,如果像原來的fun1那樣不使用arguments.callee,函數調用之後就會返回0。可是,在解除了函數體內的代碼與函數名的耦合狀態之後,newfun()仍然能正常進行階乘的計算。而fun2(),如今特只能返回0.var newfun=fun2; fun2=function(){ return 0; }; alert(newfun(5)); //120 alert(fun2(5)); //0
另一個函數內部的特殊對象是this,this引用的是函數據以執行操作的對象,或者說,this是函數在執行時所處的作用域(當在網頁的全局作用時,this對象引用的是window),看例子:
這個函數中sayColor()是在全局作用域中定義的,它引用了this對象,由於在調用函數前,this的值並不確定,因此this可能是會在代碼執行的時候引用不同的對象。當在全局作用域中調用sayColor時,this引用的是window,於是結果返回”red“。然而,當把這個函數賦給對象o,並調用o.sayColor()時,this引用的對象是o,因此對this.color求值會轉換成對o.color的求值,結果就返回了“blue”。window.color="red"; var o={color:"blue"}; function sayColor(){ alert(this.color); } sayColor(); //"red" o.sayColor=sayColor; o.sayColor(); //"blue"
注意:函數的名字僅僅是一個包含指針的變量而已,因此,即使是在不同的環境中執行,全局的sayColor()函數與o.sayColor()指向的仍然是同一個函數。
Javascript對象arguments和this
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.