最近更新: 2007-02-13

The practice of anonymous recursion function in JavaScript, by callee

我在前文《The practice of anonymous recursion function in JavaScript,》寫完之後,又到 Google 找尋是否有其它解法,結果讓我找到用 callee 的作法。這作法更簡單。

根據 ECMA-262 規範內容, callee 是 Arguments object 的屬性,不是 Function object 的屬性。難怪我在 Function object 的章節 (ch.15.3) 中找不到相關說明。關於 callee 的說明所佔篇幅不多,只有兩行:

A property is created with name callee and property attributes {DontEnum}. This initial value of this property is the Function object being executed. This allows anonymous functions to be recursive. ECMA-262 Ch.10.1.8 Arguments Object

好吧,寫程式前不先找 Google 拜碼頭,結果就是多繞一段路。規範中明言 (雖然只有兩行) , callee 指涉對象就是函數自身,因此用不著 this 了。我們只要將函數的 arguments.callee 屬性做為運算元參與 operator( ) 運算即可。整個匿名遞迴函數改寫如下:

var d =
(function(node) {
    if (!node) return '';
    var t=[];
    for (var n = node.firstChild; n; n = n.nextSibling) {
        if (n.nodeType == 3) t.push(n.nodeValue);
        else t.push(arguments.callee(n));
    }
    return t.join('');
})(
    (function(tagName, className) {
        var ds = document.getElementsByTagName(tagName, className);
        for (var i = 0; i < ds.length; ++i) {
            if (ds[i].className == className) {
                return ds[i];
            }
        }
    })('div', 'main')
);
關於 arguments:每一個函數被調用時, JavaScript 都會為其 arguments 屬性配置一個 Arguments object 的實例。此實例為一陣列,儲放了此次調用行為的引數。故 arguments[0] 是第一個引數, arguments[arguments.length-1] 是最後一個引數。除此之外, JavaScript 還會設定此 Arugments object 之實例 (即 arguments) 的 callee 屬性指涉此次被調用的函數。
樂多舊網址: http://blog.roodo.com/rocksaying/archives/2721669.html