JS實現重載


在js中,我們實現重載常用的方式有:

1、根據傳入參數的類型執行不同的操作。

2、利用參數中特殊的參數值進行不同的操作。

3、根據參數的個數進行重載。

這里對第三種重載方式的實現進行說明。

實現第三種方法,最簡單的就是使用switch case進行參數個數的判斷,然后執行相應的操作,但這樣的判斷方法導致代碼不是很整潔,逼格也不算是太高。

如:

 function fn() {
            switch (arguments.length) {
                case 0:
                    //執行語句塊
                    break;
                case 1:
                    //執行語句塊
                    break;
                case 2:
                    //執行語句塊
                    break;
                default:
                    break;
            }
        }

下面介紹一種方法,先不考慮是否適用,但可以通過了解這種重載方式,讓我們學到一些JS中的技巧和對閉包的一些理解。畢竟多了解些不算件壞事。

先上代碼:

 var arr = {
            value: ["a", "b", "c"]
        };
        bindMethod(arr, "find", function () {
            console.log(0)
        });
        bindMethod(arr, "find", function (a) {
            console.log(1)
        });
        bindMethod(arr, "find", function (a, b) {
            console.log(2)
        });
        function bindMethod(obj, name, fn) {
            var old = obj[name]; //每個方法中都會存在一個各自的old對象,產生了閉包
            obj[name] = function () {
                if (fn.length == arguments.length) {  //這里的fn.length是方法定義參數的個數,和arguments.length傳入的個數是兩回事
                    return fn.apply(this, arguments); //返回傳入在匿名函數,執行
                }
                else {
                    return old.apply(this, arguments); //返回數組的方法,再次向上進行查找
                }
            }
        }
        arr.find(); //0
        arr.find(1);  //1
        arr.find(1, 2);  //2
        arr.find(1, 2, 3); //Uncaught TypeError: Cannot read property 'apply' of undefined
       
/**
第一次進行綁定時,先賦值old,因為attr.find並沒有被創建,所以old=undefined。然后為arr對象find屬性創建一個匿名方法,這個匿名方法fn.length=1。 第二次進行綁定時,將old對象指向第一次創建的匿名方法,然后會將arr對象find屬性指向到當前創建的匿名方法,因為old指向上個方法的引用,這就會造成上個方法不會被釋放。 第三次也是一樣的步驟,保證第二次綁定的方法不會被釋放。 重載方法的執行,像一個鏈條一樣,先從最后綁定的方法內部開始尋找 方法定義的參數個數和傳入的個數是否匹配,如果匹配則返回當前的傳入的匿名函數,否則繼續向上查找,直到找到為止。 如果最后沒有找到結果,當前程序會報錯,因為第一次綁定方法時,old對象是一個undefined *
*/

 

綁定階段

先將arr綁定三個方法,每個方法都有一個old的對象,存放之前保存的方法,以此類推,(當前的方法中,old對象都會指向上一次綁定方法,但是注意,在第一次綁定的方法中,old對象是undefind),這樣就可以形成一個鏈條。也就是說內存中分別有三個attr.find的內存空間,都指向各自創建bindMethod內的匿名方法。

調用階段
當傳入0個參數,進行調用時,會先調用最后一個綁定的方法。然后進行判斷,如果傳入參數為2個,則返回匿名方法,否則
調用old指向的上個方法。再次進入,再次進行判斷,直到找到符合參數個數的方法,返回它的匿名函數。

在這里對於attr對象的綁定,其實是進行了三次綁定覆蓋的操作,依次進行對attr.find進行賦值,最后只保留最后一次的賦值對象。

這也是為什么在進行調用時,是從最后一次綁定的方法中開始執行的原因。對於attr.find方法被覆蓋,但卻沒有被自動釋放的原因是因為新方法的old

始終指向被覆蓋的方法,所以這里產生了閉包。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM