函數內部的特殊對象arguments

首先,我們應該明確:arguments是對象,而不是數組(它不是Array的實例)。我們可以理解爲函數的參數使用數組來存儲的,arguments對象可以訪問這個數組,而訪問的方法就是使用方括號。
函數不介意傳進來幾個參數,例如:你定義的函數接受兩個參數,你實際傳入一個參數或是三個參數或是不傳參都是可以的,不會報錯。我們甚至可以在函數內部改變arguments對應的數組。arguments對象的長度由實際傳入的參數個數決定,與函數定義的參數個數無關,與函數內部對數組的操作無關,但是,改變arguments.length會生效。

function f(b, c) {
        arguments[3] = c;
        console.log(arguments[3] + c); //2
        console.log(arguments.length); //3
        arguments.length = 4;
        console.log(arguments.length); //4
    }

f(1, 1, 1);

還有一個有趣的現象就是,arguments的值永遠與對應命名參數的值保持同步。

function add (num1, num2) {
    arguments[1] = 10;
    alert(arguments[0] + num2);
}

這個函數會重寫第二個參數,與此同時函數內部num2的值也變爲10,這並不是說讀取這兩個值會訪問相同的內存空間,它們的內存空間是獨立的。(這是《JS高程》上說的,不知道該怎麼證明)
注:以上結論是在非嚴格模式下得出的。

arguments對象還有一個callee屬性,該屬性是一個指針,指向擁有這個arguments的函數,我們可用該屬性消除緊密耦合現象。如階乘函數的實現:

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

arguments還有一個屬性caller,該屬性保存着調用當前函數的函數的引用。

發佈了35 篇原創文章 · 獲贊 15 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章