javascript中caller與callee的作用以及用法

javascript中caller與callee的作用以及用法

這兩個關鍵字在平時編碼中幾乎難以用到,但它們既然存在於javascript語言體系中,那麼還是有必要了解下。

caller是javascript函數類型的一個屬性,它引用調用當前函數的函數

function func() {
    alert(func.caller);
}

function func1() {
    func();
}

func1();

比如上面的代碼, 因爲func函數是杯func1函數調用的, 所以func函數中對caller的引用就是func1函數。如果func函數直接在頂層的javascript環境中被調用,那麼caller將返回null。

我們可以利用caller的特性跟蹤函數的調用鏈

function func() {
    let caller = func.caller;
    while(caller != null) {
        console.log(caller.name);
        caller = caller.caller;
    }
}

function func1() {
    func();
}

function func2() {
    func1();
}

function func3() {
    func2();
}

func3();

以上代碼將func3到func的函數調用鏈打印出來。

callee則不是函數對象的屬性,它是函數上下文中arguments對象的屬性

function func() {
    alert(arguments.callee);
}

它引用的是函數自身,在上面的代碼中,arguments.callee引用的就是func函數本身。既然他引用的是函數本身,那麼似乎顯得有點多餘,當我們需要在函數體內使用函數本身時,直接通過函數名調用就可以了,幹嘛還要多此一舉的通過arguments.callee這樣去調用。然而我覺得callee存在的意義可能是想解耦函數本身對函數名稱的依賴吧, 比如說在遞歸的環境下,函數內部通常還要調用函數本身, 而調用函數本身就免不了硬編碼函數名稱, 如果函數名稱有變化, 那麼函數中的代碼也需要修改,使用callee就可以避免此類情況。

function factorial( num ) {
    if( num == 1 ) {
        return 1;
    }
    let result = num * factorial(num - 1);
    return result;
}

alert(factorial(100));

上面的階乘函數通過callee可以改造成

function factorial( num ) {
    if( num == 1 ) {
        return 1;
    }
    let result = num * arguments.callee(num - 1);
    return result;
}

alert(factorial(100));

如此同樣實現遞歸, 但是可以做到函數體不依賴函數名稱。

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