【jq源碼探祕】— js如何實現實現重載

你們都知道js是沒有重載的,可是經過某種方式是能夠實現的,下面就是jq的實現方式:
/*給某個對象添加方法的函數*/
    function addMethod(object, name, fn) {
        var old = object[name];
        //第一次old是 undefined
        object[name] = function() {
            //若是調用函數的參數長度等於fn的參數長度,那就返回當前函數
            if (fn.length == arguments.length) {
                return fn.apply(this, arguments);
            } else if (typeof old == 'function') {
            //若是當前的調用不匹配那麼調用上一次的old,直到匹配爲止
                return old.apply(this, arguments); 
            }
        }
    }
    var people = ['1', '2', '3'];
    addMethod(people, 'finds', function() {
        return 0;
    })
    addMethod(people, 'finds', function(firstname) {
        return 1;
    })
    addMethod(people, 'finds', function(firstname, lastname) {
        return 2;
    })
    console.log(people.finds('1', '2'))
    console.log(people.finds());
    console.log(people.finds('1'));
複製代碼
憑直覺,函數重載能夠經過if…else或者switch實現,這就不去管它了。jQuery之父John Resig提出了一個很是巧(bian)妙(tai)的方法,利用了閉包。

people.find事實上只能綁定一個函數,那它爲什麼能夠處理3種不一樣的輸入呢?它不可能同時綁定3個函數find0,find1與find2啊!這裏的關鍵在於old屬性。 由addMethod函數的調用順序可知,users.find最終綁定的是find2函數。然而,在綁定find2時,old爲find1;同理,綁定find1時,old爲find0。3個函數find0,find1與find2就這樣經過閉包連接起來了。 根據addMethod的邏輯,當fn.length與arguments.length不匹配時,就會去調用old,直到匹配爲止。bash

相關文章
相關標籤/搜索