摘要:中的函數(shù)本身就是對象,可以攜帶自身狀態(tài),另外還有化等函數(shù)式編程的方法讓函數(shù)緩存狀態(tài),基本上沒有仿函數(shù)存在的必要。
Functor
仿函數(shù)(Functor)是 C++ 里面一個重要的概念,簡而言之就是使用重載了 operator() 運算符的對象模仿函數(shù)的行為,帶來的收益是仿函數(shù)可以攜帶自身狀態(tài),普通的 C++ 函數(shù)不是對象,做不到這一點。
js 中的函數(shù)本身就是對象,可以攜帶自身狀態(tài),另外還有 curry 化等函數(shù)式編程的方法讓函數(shù)緩存狀態(tài),基本上沒有仿函數(shù)存在的必要。最簡單的你可以這樣寫:
function foobar() { return foobar.a; } foobar.a = 1; var b = foobar(); // b=>1
這樣,foobar 就攜帶了自身狀態(tài) a,并且可以在函數(shù)體重訪問 a。
但是這里有一個問題:函數(shù)體中 foobar.a 這一句是利用閉包實現(xiàn)的,其中 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=>1js 實現(xiàn)
那么怎么實現(xiàn)呢?我之前寫了一篇文章,里面說 js 不容易實現(xiàn)類似的概念。但是當時我沒細想,今天試了一下其實變動一下接口,還是能實現(xiàn)類似效果的。
基本的原理就是這樣:
function f() {...} var functor = f.bind(f);
讓一個函數(shù) bind 它自己,這樣它不就能用 this 訪問自己了嗎?但是這里還有個問題,bind 的返回結(jié)果并不是 f 自身而是另一個函數(shù),functor 的持有者在外部訪問不到 f。所以這里還要用 js 的新 api defineProperty 處理一下,使得對 functor 的某些屬性訪問,轉(zhuǎn)移到 f 上去。
完整的實現(xiàn)如下:
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,我們可以通過一個函數(shù) fn 創(chuàng)建很多個 functor,每一個都有自身的狀態(tài),互不影響。并且在 fn 中我們可以使用 this 訪問自身狀態(tài)。比如:
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"
最后,這只是個腦洞!每個語言都有自身的規(guī)律和方法論。不要真的在項目里這么寫,除非你的項目目的就是創(chuàng)造漂亮的語法。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/86418.html
摘要:在我們上面的例子里,的輸入和返回值是一樣的數(shù)據(jù)類型,都是。所以我們可以寫一個服務于函數(shù)的么答案是肯定的但怎么拆開一個函數(shù)是個問題簡單點兒,你可以直接執(zhí)行這個函數(shù),然后用她的返回值。我們來拿試一下聲明了一個函數(shù)的參數(shù)及返回值的形態(tài)。 Functors 先看看如下代碼: function plus1(value) { return value + 1; } 這就是一個普通函數(shù),...
摘要:簡單說,我想實現(xiàn)這么一個功能假設有一個對象,他的方法支持鏈式調(diào)用。本來是立即執(zhí)行的代碼,通過的包裝,成了一個函數(shù),我可以把存儲起來在任意時刻調(diào)用,相當于執(zhí)行檢查。 我相信讀到本文標題的人基本上是懵 B 的,我實在想不出更好的表述方法。簡單說,我想實現(xiàn)這么一個功能: 假設有一個對象 foobar,他的方法支持鏈式調(diào)用。比如這樣: var foobar = new Foobar(); f...
摘要:函數(shù)式編程二拖延癥了好久,第二篇終于寫出來了。如果你對熟悉的話應該還記得,是可以調(diào)用來集中處理錯誤的對于函數(shù)式編程我們也可以做同樣的操作,如果運行正確,那么就返回正確的結(jié)果如果錯誤,就返回一個用于描述錯誤的結(jié)果。 JavaScript函數(shù)式編程(二) 拖延癥了好久,第二篇終于寫出來了。 上一篇在這里:JavaScript函數(shù)式編程(一) 上一篇文章里我們提到了純函數(shù)的概念,所謂的純函數(shù)...
摘要:電子表格使用語言電子表格是辦公軟件的必備,我們最熟知的是微軟的。文中用框架來實現(xiàn)一個簡單的電子表格,所用代碼僅行。 showImg(https://segmentfault.com/img/remote/1460000019770011); 本文原創(chuàng)并首發(fā)于公眾號【Python貓】,未經(jīng)授權(quán),請勿轉(zhuǎn)載。 原文地址:https://mp.weixin.qq.com/s/Ob... 今天,...
閱讀 1456·2019-08-30 12:54
閱讀 1937·2019-08-30 11:16
閱讀 1670·2019-08-30 10:50
閱讀 2550·2019-08-29 16:17
閱讀 1345·2019-08-26 12:17
閱讀 1437·2019-08-26 10:15
閱讀 2453·2019-08-23 18:38
閱讀 842·2019-08-23 17:50