国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

JavaScript中有趣的反柯里化

來源:懂視網 責編:小采 時間:2020-11-27 20:30:41
文檔

JavaScript中有趣的反柯里化

JavaScript中有趣的反柯里化:反科里化的話題來自javascript之父Brendan Eich去年的一段twitter. 近幾天研究了一下,覺得這個東東非常有意思,分享一下。先忘記它的名字,看下它能做什么.不要小看這個功能,試想下,我們在寫一個庫的時候,時常會寫這樣的代碼,拿webQQ的Jx庫舉例。
推薦度:
導讀JavaScript中有趣的反柯里化:反科里化的話題來自javascript之父Brendan Eich去年的一段twitter. 近幾天研究了一下,覺得這個東東非常有意思,分享一下。先忘記它的名字,看下它能做什么.不要小看這個功能,試想下,我們在寫一個庫的時候,時常會寫這樣的代碼,拿webQQ的Jx庫舉例。
反科里化的話題來自javascript之父Brendan Eich去年的一段twitter. 近幾天研究了一下,覺得這個東東非常有意思,分享一下。先忘記它的名字,看下它能做什么.

20120301085946697.png

不要小看這個功能,試想下,我們在寫一個庫的時候,時常會寫這樣的代碼,拿webQQ的Jx庫舉例。

20120301085946697.png

我們想要的,其實只是借用Array原型鏈上的一些函數。并沒有必要去顯式的構造一個新的函數來改變它們的參數并且重新運算。

如果用uncurrying的方式顯然更加優雅和美妙,就像這樣:

20120301085946697.png

還能做很多有趣和方便的事情.

甚至還能把call和apply方法都uncurrying,把函數也當作普通數據來使用. 使得javascript中的函數調用方式更像它的前生scheme, 當函數名本身是個變量的時候, 這種調用方法特別方便.

scheme里面調用函數是這樣:

20120301085946697.png

javascript里可以寫的很接近.

20120301085946697.png

再看看jquery庫,由于jquery對象( 即通過$()創建的對象 )是一個對象冒充的偽數組,它有length屬性,并且能夠通過下標查找對應的元素,當需要給jquery對象添加一個成員時, 偽代碼大概是:

20120301085946697.png

如果用uncurrying的話, 就可以

20120301085946697.png

借用了array對象的push函數, 讓引擎去自動管理數組成員和length屬性.

而且可以一次把需要的函數全部借過來, 一勞永逸. 一段測試代碼:

20120301085946697.png

總的來說, 使用uncurrying技術, 可以讓任何對象擁有原生對象的方法. 好了,如果到這里依然沒有引起你的興趣,那么你可以去干點別的了。

接下來一步一步來看看原理以及實現。

在了解反currying化這個奇怪的名字之前,我們得先搞清楚currying。

維基百科上的定義:科里化( currying ); 又稱部分求值,是把接受多個參數的函數變換成接受一個單一參數的函數,并且返回接受余下的參數并且返回結果的新函數的技術。

通俗點講,currying有點類似買房子時分期付款的方式,先給一部分首付( 一部分參數 ), 返回一個存折( 返回一個函數 ),合適的時候再給余下的參數并且求值計算。

來看看我們都用過的currying, 我們經常在綁定context 的時候實現一個Function.prototype.bind函數.

20120301085946697.png

高階函數是實現currying的基礎, 所謂高階函數至少滿足這2個特性:

1, 函數可以當作參數傳遞,

2, 函數可以作為返回值。

Javascript在設計之初,參考了很多scheme語言的特性。而scheme是函數式語言鼻祖lisp的2大方言之一,所以javascript也擁有一些函數式語言的特性,包括高階函數,閉包,lambda表達式等。

當javascript中的函數返回另一個函數,此時會形成一個閉包,而在閉包中就可以保存第一次運算的參數,我們用這個思想,來寫一個通用的currying函數。

20120301085946697.png

我們約定, 當傳入參數時候, 繼續currying化, 參數為空時才開始求值.

假設在實現一個計算每月花費的函數, 每天結束前我們都要記錄今天花了多少錢, 但我們只關心月底的花費總值, 無需每天都計算一次.

20120301085946697.png

使用currying函數, 便可以延遲到最后一刻才一起計算, 好處不言而喻, 在很多場合可以避免無謂的計算, 節省性能, 也是實現惰性求值的一種方案.

好了,現在才走進正題,

curring是預先填入一些參數.

反curring就是把原來已經固定的參數或者this上下文等當作參數延遲到未來傳遞.

其實就是搞這樣一個事情,將:

1

obj.foo( arg1 ) //foo本來是只在obj上的函數. 就像push原本只在Array.prototype上

轉化成這樣的形式

1

foo( obj, arg1 ) // 跟我們舉的第一個例子一樣.將[].push轉換成push( [] )

就像原本是接在電視插頭上的插座,把它拆下來之后,其實也能用來接冰箱。

Ecma上Array和String的每個原型方法后面都有這么一段話,比如push:

NOTE The push function is intentionally generic; it does not require that its this value be an Array object.

Therefore it can be transferred to other kinds of objects for use as a method. Whether the concat function can be applied.

Javascript為什么要這樣設計, 我們先來復習下動態語言中重要的鴨子類型思想.

說個故事:

很久以前有個皇帝喜歡聽鴨子呱呱叫,于是他召集大臣組建一個一千只鴨子的合唱團。大臣把全國的鴨子都抓來了,最后始終還差一只。有天終于來了一只自告奮勇的雞,這只雞說它也會呱呱叫,好吧在這個故事的設定里,它確實會呱呱叫。 后來故事的發展很明顯,這只雞混到了鴨子的合唱團中。— 皇帝只是想聽呱呱叫,他才不在乎你是鴨子還是雞呢。

這個就是鴨子類型的概念,在javascript里面,很多函數都不做對象的類型檢測,而是只關心這些對象能做什么。

Array構造器和String構造器的prototype上的方法就被特意設計成了鴨子類型。這些方法不對this的數據類型做任何校驗。這也就是為什么arguments能冒充array調用push方法.

看下v8引擎里面Array.prototype.push的代碼:

function ArrayPush() {

var n = TO_UINT32( this.length );

var m = %_ArgumentsLength();

for (var i = 0; i < m; i++) {

this[i+n] = %_Arguments(i); //屬性拷貝

this.length = n + m; //修正length

return this.length;

}

}

可以看到,ArrayPush方法沒有對this的類型做任何顯示的限制,所以理論上任何對象都可以被傳入ArrayPush這個訪問者。

我們需要解決的只剩下一個問題, 如何通過一種通用的方式來使得一個對象可以冒充array對象。

真正的實現代碼其實很簡單:

20120301085946697.png

這段代碼雖然很短, 初次理解的時候還是有點費力. 我們拿push的例子看看它發生了什么.

var push = Array.prototype.push.uncurrying();

push( obj, ‘first’ );

20120301085946697.png

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

JavaScript中有趣的反柯里化

JavaScript中有趣的反柯里化:反科里化的話題來自javascript之父Brendan Eich去年的一段twitter. 近幾天研究了一下,覺得這個東東非常有意思,分享一下。先忘記它的名字,看下它能做什么.不要小看這個功能,試想下,我們在寫一個庫的時候,時常會寫這樣的代碼,拿webQQ的Jx庫舉例。
推薦度:
標簽: js 有趣 有意思
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 欧美国产日韩在线播放 | 免费中国女人69xxxxx视频 | 日韩欧美国产综合 | 亚洲精品99久久久久中文字幕 | 午夜视频免费看 | 欧美爱爱网址 | 色老头久久久久久久久久 | 久久久网久久久久合久久久久 | 美女a级毛片 | 一区二区三区视频 | 久久国产精品视频 | 伊人久久成人成综合网222 | 香蕉久久ac一区二区三区 | 欧美第一页在线 | 成人看免费一级毛片 | 久久久国产精品视频 | 国产欧美日韩另类 | 日韩精品第一页 | 亚洲色欧美 | 久久精品亚洲一区二区 | 亚洲国产精品欧美日韩一区二区 | 国产精品亚洲精品观看不卡 | 国产日韩欧美综合 | 久久伊人中文字幕有码 | 在线看精品 | 欧美一页| 欧美伊人久久大香线蕉综合69 | 日本一区二区不卡在线 | 国产码欧美日韩高清综合一区 | 国产高清不卡一区二区三区 | 国产阿v| 日韩欧美亚州 | 中文日韩欧美 | 亚洲综合无码一区二区 | 国产精品伦一区二区三级视频 | 欧美国产精品va在线观看 | 中文在线第一页 | 成人欧美一区二区三区黑人 | 亚洲欧美中文日韩在线 | 国产成人综合久久 | 欧美整片第一页 |