欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
javascript中有趣的反柯里化深入分析

javascript中有趣的反柯里化深入分析


        國內對前端的研究在某些方面也不遜色于國外,反科里化的話(huà)題來(lái)自javascript之父Brendan Eich去年的一段twitter,需要深入理解的朋友可以參考本文

寫(xiě)在前面的話(huà):國內對前端的研究在某些方面也不遜色于國外,這篇文章雖然看不太懂,但我很欣賞這種深入研究的精神!

反科里化的話(huà)題來(lái)自javascript之父Brendan Eich去年的一段twitter. 近幾天研究了一下,覺(jué)得這個(gè)東東非常有意思,分享一下。先忘記它的名字,看下它能做什么.

不要小看這個(gè)功能,試想下,我們在寫(xiě)一個(gè)庫的時(shí)候,時(shí)常會(huì )寫(xiě)這樣的代碼,拿webQQ的Jx庫舉例。


我們想要的,其實(shí)只是借用Array原型鏈上的一些函數。并沒(méi)有必要去顯式的構造一個(gè)新的函數來(lái)改變它們的參數并且重新運算。

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

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

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

scheme里面調用函數是這樣:

javascript里可以寫(xiě)的很接近.

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

如果用uncurrying的話(huà), 就可以

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

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

總的來(lái)說(shuō), 使用uncurrying技術(shù), 可以讓任何對象擁有原生對象的方法. 好了,如果到這里依然沒(méi)有引起你的興趣,那么你可以去干點(diǎn)別的了。

接下來(lái)一步一步來(lái)看看原理以及實(shí)現。
在了解反currying化這個(gè)奇怪的名字之前,我們得先搞清楚currying。

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

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

來(lái)看看我們都用過(guò)的currying, 我們經(jīng)常在綁定context 的時(shí)候實(shí)現一個(gè)Function.prototype.bind函數.

高階函數是實(shí)現currying的基礎, 所謂高階函數至少滿(mǎn)足這2個(gè)特性:
1,函數可以當作參數傳遞,
2,函數可以作為返回值。

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

當javascript中的函數返回另一個(gè)函數,此時(shí)會(huì )形成一個(gè)閉包,而在閉包中就可以保存第一次運算的參數,我們用這個(gè)思想,來(lái)寫(xiě)一個(gè)通用的currying函數。

我們約定, 當傳入參數時(shí)候, 繼續currying化, 參數為空時(shí)才開(kāi)始求值.

假設在實(shí)現一個(gè)計算每月花費的函數, 每天結束前我們都要記錄今天花了多少錢(qián), 但我們只關(guān)心月底的花費總值, 無(wú)需每天都計算一次.

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

好了,現在才走進(jìn)正題,

curring是預先填入一些參數.

反curring就是把原來(lái)已經(jīng)固定的參數或者this上下文等當作參數延遲到未來(lái)傳遞.

其實(shí)就是搞這樣一個(gè)事情,將:

obj.foo( arg1 ) //foo本來(lái)是只在obj上的函數. 就像push原本只在A(yíng)rray.prototype上

轉化成這樣的形式

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

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

Ecma上Array和String的每個(gè)原型方法后面都有這么一段話(huà),比如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為什么要這樣設計, 我們先來(lái)復習下動(dòng)態(tài)語(yǔ)言中重要的鴨子類(lèi)型思想.

說(shuō)個(gè)故事:

很久以前有個(gè)皇帝喜歡聽(tīng)鴨子呱呱叫,于是他召集大臣組建一個(gè)一千只鴨子的合唱團。大臣把全國的鴨子都抓來(lái)了,最后始終還差一只。有天終于來(lái)了一只自告奮勇的雞,這只雞說(shuō)它也會(huì )呱呱叫,好吧在這個(gè)故事的設定里,它確實(shí)會(huì )呱呱叫。 后來(lái)故事的發(fā)展很明顯,這只雞混到了鴨子的合唱團中?!?皇帝只是想聽(tīng)呱呱叫,他才不在乎你是鴨子還是雞呢。

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

Array構造器和String構造器的prototype上的方法就被特意設計成了鴨子類(lèi)型。這些方法不對this的數據類(lèi)型做任何校驗。這也就是為什么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方法沒(méi)有對this的類(lèi)型做任何顯示的限制,所以理論上任何對象都可以被傳入ArrayPush這個(gè)訪(fǎng)問(wèn)者。

我們需要解決的只剩下一個(gè)問(wèn)題, 如何通過(guò)一種通用的方式來(lái)使得一個(gè)對象可以冒充array對象。

真正的實(shí)現代碼其實(shí)很簡(jiǎn)單:

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

復制代碼 代碼如下:

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

push( obj, ‘first' );

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
輕松學(xué)習 JavaScript——第 4 部分:函數中的 arguments 對象
JavaScript中的原型和繼承
Scala函數式編程徹底精通
深入理解JavaScript系列(49):Function模式(上篇)
一文帶你搞懂JavaScript Currying(柯里化)函數
學(xué)習JavaScript 的必備 (一),讓您對js的 function, javascr...
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久