国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

實現一個奇怪的需求:如何將一串 js 鏈式調用存儲在一個函數或對象中,以備未來調用?

jerry / 2150人閱讀

摘要:簡單說,我想實現這么一個功能假設有一個對象,他的方法支持鏈式調用。本來是立即執行的代碼,通過的包裝,成了一個函數,我可以把存儲起來在任意時刻調用,相當于執行檢查。

我相信讀到本文標題的人基本上是懵 B 的,我實在想不出更好的表述方法。簡單說,我想實現這么一個功能:

假設有一個對象 foobar,他的方法支持鏈式調用。比如這樣:

var foobar = new Foobar();

foobar.segment(1).fault(2);

注意 segmentfault 并不一定返回 this,但是要返回一個同類型對象,否則 foobar.segment(1).fault(2).segment(3).fault(4) 這樣的代碼就可能不合法。這是我特別添加的約束,滿足這一條下面的文章和才有意義

現在我想實現一個包裝函數 makePolicy,實現這樣的語法(假設 Foobar 所有方法都支持鏈式調用):

var policy = makePolicy(Foobar).segment(1).fault(2);
var foobar = new Foobar();

policy(foobar); // 等效于調用 foobar.segment(1).fault(2)

這里比較難實現的,就是 makePolicy(Foobar).segment(1).fault(2)這句代碼。如果沒有這個需求,那直接這樣寫好了:

var policy = function (that) {
    var newThat = Foobar.prototype.segment.call(that, 1);
    Foobar.prototype.fault.call(newThat , 2);
};
var foobar = new Foobar();

policy(foobar); // 等效于調用 foobar.segment(1).fault(2)

之所以有這樣的需求,主要是為了完善 js 參數檢查器(這篇文章)中的邏輯連接的功能。為了方便使用,我想寫出這樣的接口:

// 檢查 param 是否在區間(1,3) 與 (2,4) 的交集內
check(param, "param").and(check.policy.gt(1).lt(3), check.policy.gt(2).lt(4));

// 檢查 param 是否在區間(1,2) 與 (3,4) 的并集內
check(param, "param").or(check.policy.gt(1).lt(2), check.policy.gt(3).lt(4));

function myCheck(obj) {
    return obj.length > 4;
}

// 檢查 param 是否是數組并且長度大于 4
check(param, "param").and(check.policy.is("array"), myCheck);

// 檢查 param 是否*不是*[1,3]之間的偶數(即2)
check(param, "param").not.and(
    check.policy.is("number").not.lt(1).not.gt(3),
    function (obj) {
        return obj % 2 === 0;
    });

上面的代碼中,check.policy.gt(1).lt(3) 就是我想實現的語法功能。本來 check(a).gt(1).lt(3) 是立即執行的代碼,通過 policy 的包裝,var fn = check.policy.gt(1).lt(3) 成了一個函數,我可以把 fn 存儲起來在任意時刻調用,相當于執行 gt(1).lt(3) 檢查。

需求講清楚了,剩下的就是開腦洞了。對照下面的代碼梳理一下思路:

var policy = makePolicy(Foobar).segment(1).fault(2);
var foobar = new Foobar();

policy(foobar); // 等效于調用 foobar.segment(1).fault(2)

首先,我實驗了一下,policy 的語法設想實際上很難實現,因為 js 中沒有方便的語法表達“函數類”、“函數實例”這樣的概念,所以 policy 不適合設計為一個函數,妥協一下,把 policy 設計為一個 包含 exec 方法的對象,調用 policy.exec(...) 即可執行相應功能。

第二,將 policy 設計為一個 Policy 類的實例,因為 policy 可能會有很多方法,這些方法是在 makePolicy 函數中從輸入類原型上按照名字一個一個扒下來的,比較適合放在 prototype 中。以及,根據輸入類的不同,Policy 應該在 makePolicy 中動態生成,然后立即 new 一個實例返回,這樣我們可以隨時生成任意類的 policy 包裝。

綜合以上思考,我們要實現的接口改為這樣:

var policy = makePolicy(Foobar);
var functor = policy.segment(1).fault(2); // fn 存儲了鏈式調用的路徑和參數
var foobar = new Foobar();

functor.exec(foobar); // 等效于調用 foobar.segment(1).fault(2)

下面是簡化的實現代碼:

/**
 * 生成 policy
 * @param proto 要生成 policy 的類原型
 * @return 生成的 policy 實例
 */
function makePolicy(proto) {
    function Policy(fn, prev) {
        this.fn_ = fn;
        this.prev_ = prev;
    }

    Policy.prototype.exec = function (that) {
        var myThat = that;
        var prev = this.prev_;
        var fn = this.fn_;

        if (prev) {
            myThat = prev.exec(that);
        }

        return fn(myThat);
    };

    for (var key in proto) {
        if (proto.hasOwnProperty(key)) {
            Policy.prototype[key] = (function (fnName) {
                return function () {
                    var self = this;
                    var args = Array.prototype.slice.call(arguments, 0);

                    return new Policy(function (that) {
                        return proto[fnName].apply(that, args);
                    }, self);
                }
            })(key);
        }
    }
    
    return new Policy();
}

由上面的代碼可知,當我們在鏈式調用函數時,順序是從左到右。而 policy 在運行時,是先調用最右邊的 policy 然后通過 prev_ 指針一路回溯到最左邊,然后再從左到右執行下來。

有了上面的實現,js 參數檢查器(這篇文章)的功能差不多就完整了,有興趣的同學可以在這里看到具體實現。不過目前的實現仍然有許多限制,在目前的基礎上,我們其實可以實現更加通用,無所謂是不是鏈式調用的 policy 語法,等我做出來在寫文章匯報。

最后請教一個問題:policy 這個名字是我瞎起的,這樣的功能應該叫什么名字呢?roadmap?blueprint?想不出來。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87805.html

相關文章

  • JavaScript 工作原理之四-事件循環及異步編程出現和 5 種更好 async/await

    摘要:函數會在之后的某個時刻觸發事件定時器。事件循環中的這樣一次遍歷被稱為一個。執行完畢并出棧。當定時器過期,宿主環境會把回調函數添加至事件循環隊列中,然后,在未來的某個取出并執行該事件。 原文請查閱這里,略有改動。 本系列持續更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第四章。 現在,我們將會通過回顧單線程環境下編程的弊端及如何克服這些困難以創建令人驚嘆...

    maochunguang 評論0 收藏0
  • JavaScript 未來:它還少些什么?

    摘要:例如通過哈希表映射需要一個操作來檢查值是否相等,另一個操作用于創建哈希碼。如果使用哈希碼,則對象應該是不可變的。模式匹配提案目前處于第階段。在本文,我們研究其中的智能管道另一個提議被稱為。更強大,更重量級,并附帶自己的數據結構。 翻譯:瘋狂的技術宅原文:http://2ality.com/2019/01/fut... 本文首發微信公眾號:jingchengyideng歡迎關注,每天...

    layman 評論0 收藏0
  • javascript 回調函數 整理

    摘要:回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用于對該事件或條件進行響應。若是使用回調函數進行處理,代碼就可以繼續進行其他任務,而無需空等。參考理解回調函數理解與使用中的回調函數這篇相當不錯回調函數 為什么寫回調函數 對于javascript中回調函數 一直處于理解,但是應用不好的階段,總是在別人家的代碼中看到很巧妙的回調,那時候會有wow c...

    xiaowugui666 評論0 收藏0

發表評論

0條評論

jerry

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<