初學JavaScript之arguments、caller、callee、call、apply理解

同樣在開始前爲了方便打印,添加一個函數

Object.prototype.description = function()
{
    console.log(this);
}

arguments

arguments對象代表正在執行的函數和調用它的函數的參數。

//通過例子很好說明
function printArguments()
{
    for(arg in arguments)
    {
        arguments[arg].description();
    }
}
printArguments(1,"yes",[1,2,3,4]);
//輸出:
//[Number: 1]
//[String: 'yes']
//[ 1, 2, 3, 4 ]
//[Function]  //這個可以忽視,這個是上面添加的description()方法。

caller
返回一個對函數的引用,該函數調用了當前函數。

function f1()
{
    if (f1.caller)
    {
        f1.caller.description();
    }else{
        "this is a top function".description();
    }
}

function f2()
{
    f1();
}
f2();
// 打印結果是:[Function: f2]

callee
callee 屬性的初始值就是正被執行的 Function 對象。
callee 屬性是 arguments 對象的一個成員,它表示對函數對象本身的引用,這有利於匿名
函數的遞歸或者保證函數的封裝性

// 打印函數本身
function func()
{
    arguments.callee.description()
}
func();   // [Function: func]

// 可以用於驗證形參和實參
function calleeDemo(arg1,arg2)
{
    arguments.length.description();         //arguments.length是實參長度
    arguments.callee.length.description();  //arguments.callee.length是形參長度
}
calleeDemo(1);        // [Number: 0]  [Number: 2]
calleeDemo(1,2);      // [Number: 2]  [Number: 2]
calleeDemo(1,2,3);    // [Number: 3]  [Number: 2]

// 用於遞歸  1+2+3+....
var sum = (function(n){
    return n <= 0 ? 0 : (n + arguments.callee(n-1));
})(100);
sum.description();  // [Number: 5050]

apply 和 call
它們的作用都是將函數綁定到另外一個對象上去運行。兩者僅在定義參數方式有所區別。
apply(thisArg,argArray);

call(thisArg,arg1,arg2…);
也可以說它們將函數對象的上下文從初始的上下文改變爲由thisArg指定的新對象。

// 瞭解一下
function sayHi()
{
    ("Hello, "+ this.name + ".").description();
}
var person = {
    name : "張三丰"
};
sayHi.call(person);//[String: 'Hello, 張三丰.']


//應用call和apply還有一個技巧在裏面,就是用call和apply應用另一個函數(類)以後,
//當前的函數(類)就具備了另一個函數(類)的方法或者是屬性,這也可以稱之爲“繼承”。
function base(){
    this.name = "奧特曼";
    this.method = function(){
        this.name.description();
    }
}

function extend()
{
    base.call(this);
    name.description();
    method.description();//[Function]
}

extend();
// 打印: //[String: '奧特曼'] //[Function]
(new extend()).method();
// 打印: //[String: '奧特曼'] //[Function] // [String: '我是奧特曼.']

/**
*上面的例子可以看出,通過call之後,extend可以繼承到base的方法和屬性。 
**/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章