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

資訊專欄INFORMATION COLUMN

開個腦洞,如何使用 javascript 實現“仿函數”(Functor)?

anRui / 1091人閱讀

摘要:中的函數本身就是對象,可以攜帶自身狀態,另外還有化等函數式編程的方法讓函數緩存狀態,基本上沒有仿函數存在的必要。

Functor

仿函數(Functor)是 C++ 里面一個重要的概念,簡而言之就是使用重載了 operator() 運算符的對象模仿函數的行為,帶來的收益是仿函數可以攜帶自身狀態,普通的 C++ 函數不是對象,做不到這一點。

js 中的函數本身就是對象,可以攜帶自身狀態,另外還有 curry 化等函數式編程的方法讓函數緩存狀態,基本上沒有仿函數存在的必要。最簡單的你可以這樣寫:

function foobar() {
    return foobar.a;
}

foobar.a = 1;
var b = foobar(); // b=>1

這樣,foobar 就攜帶了自身狀態 a,并且可以在函數體重訪問 a。

但是這里有一個問題:函數體中 foobar.a 這一句是利用閉包實現的,其中 foobar 這個引用被寫死了,從效果上看 foobar 成了一個單例。如果我想要多個 foobar 實例怎么辦呢?

以及,我比較喜歡 this 指針,而不是閉包。面對這種情況,我更喜歡這樣的寫法:

// 偽代碼

function foobar() {
    return this.b;
}

foobar.setB = function (val) {
    this.b = val
}

var foo = new foobar;
foo.setB(1);

var b = foo(); // b=>1
js 實現

那么怎么實現呢?我之前寫了一篇文章,里面說 js 不容易實現類似的概念。但是當時我沒細想,今天試了一下其實變動一下接口,還是能實現類似效果的。

基本的原理就是這樣:

function f() {...}
var functor = f.bind(f);

讓一個函數 bind 它自己,這樣它不就能用 this 訪問自己了嗎?但是這里還有個問題,bind 的返回結果并不是 f 自身而是另一個函數,functor 的持有者在外部訪問不到 f。所以這里還要用 js 的新 api defineProperty 處理一下,使得對 functor 的某些屬性訪問,轉移到 f 上去。

完整的實現如下:

function makeFunctor(fn, props) {
    function thisFn() {
        return fn.apply(this, Array.prototype.slice.call(arguments));
    }
    
    var ret = thisFn.bind(thisFn);
    
    for (var key in props) {
        if (!props.hasOwnProperty(key)) {
            continue;
        }

        Object.defineProperty(ret, key, {
            configurable : true,
            enumerable : true,
            
            get : function () {
                return thisFn[key];
            },
            
            set : function (value) {
                thisFn[key] = value;
            }
        });
        
        ret[key] = props[key];
    }
    
    return ret;
}

通過 makeFunctor,我們可以通過一個函數 fn 創建很多個 functor,每一個都有自身的狀態,互不影響。并且在 fn 中我們可以使用 this 訪問自身狀態。比如:

function hello () {
    alert("Hello, " + this.name);
}

hello.create = function () {
    makeFunctor(hello, {
        name : "Tom"
    });
}

var ftHello = hello.create();
var ftHello2 = hello.create();

ftHello(); // Hello, Tom"
ftHello.name = "Jack";
ftHello(); // Hello, Jack"

ftHello2(); // Hello, Tom"

最后,這只是個腦洞!每個語言都有自身的規律和方法論。不要真的在項目里這么寫,除非你的項目目的就是創造漂亮的語法。

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

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

相關文章

  • 理解 Redux

    摘要:我們知道狀態機是表示有限個狀態以及在這些狀態之間的轉移和動作等行為的數學模型。對照上面我們自己寫的狀態機代碼可以看出的作用告訴狀態樹發生什么變化,及所需要的數據是什么。 前言 我之前開發網站的時候一直用的是 Flux, 自從出了 Redux 之后由于種種原因沒有跟進了解,最近手頭上的事情基本忙的差不多了,抽空閱讀了 Redux 的源碼,并整理了這篇博文。 先說重點: Redux 與 R...

    leejan97 評論0 收藏0
  • [譯]函數JavaScriptFunctors

    摘要:在我們上面的例子里,的輸入和返回值是一樣的數據類型,都是。所以我們可以寫一個服務于函數的么答案是肯定的但怎么拆開一個函數是個問題簡單點兒,你可以直接執行這個函數,然后用她的返回值。我們來拿試一下聲明了一個函數的參數及返回值的形態。 Functors 先看看如下代碼: function plus1(value) { return value + 1; } 這就是一個普通函數,...

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

    摘要:簡單說,我想實現這么一個功能假設有一個對象,他的方法支持鏈式調用。本來是立即執行的代碼,通過的包裝,成了一個函數,我可以把存儲起來在任意時刻調用,相當于執行檢查。 我相信讀到本文標題的人基本上是懵 B 的,我實在想不出更好的表述方法。簡單說,我想實現這么一個功能: 假設有一個對象 foobar,他的方法支持鏈式調用。比如這樣: var foobar = new Foobar(); f...

    jerry 評論0 收藏0
  • JavaScript函數式編程(二)

    摘要:函數式編程二拖延癥了好久,第二篇終于寫出來了。如果你對熟悉的話應該還記得,是可以調用來集中處理錯誤的對于函數式編程我們也可以做同樣的操作,如果運行正確,那么就返回正確的結果如果錯誤,就返回一個用于描述錯誤的結果。 JavaScript函數式編程(二) 拖延癥了好久,第二篇終于寫出來了。 上一篇在這里:JavaScript函數式編程(一) 上一篇文章里我們提到了純函數的概念,所謂的純函數...

    booster 評論0 收藏0
  • 小型的編程項目有哪些值得推薦?這本神書寫了 22 個,個個了不得

    摘要:電子表格使用語言電子表格是辦公軟件的必備,我們最熟知的是微軟的。文中用框架來實現一個簡單的電子表格,所用代碼僅行。 showImg(https://segmentfault.com/img/remote/1460000019770011); 本文原創并首發于公眾號【Python貓】,未經授權,請勿轉載。 原文地址:https://mp.weixin.qq.com/s/Ob... 今天,...

    haitiancoder 評論0 收藏0

發表評論

0條評論

anRui

|高級講師

TA的文章

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