摘要:專(zhuān)題系列第十四篇,講解偏函數(shù)以及如何實(shí)現(xiàn)一個(gè)函數(shù)定義維基百科中對(duì)偏函數(shù)的定義為翻譯成中文在計(jì)算機(jī)科學(xué)中,局部應(yīng)用是指固定一個(gè)函數(shù)的一些參數(shù),然后產(chǎn)生另一個(gè)更小元的函數(shù)。
定義JavaScript 專(zhuān)題系列第十四篇,講解偏函數(shù)以及如何實(shí)現(xiàn)一個(gè) partial 函數(shù)
維基百科中對(duì)偏函數(shù) (Partial application) 的定義為:
In computer science, partial application (or partial function application) refers to the process of fixing a number of arguments to a function, producing another function of smaller arity.
翻譯成中文:
在計(jì)算機(jī)科學(xué)中,局部應(yīng)用是指固定一個(gè)函數(shù)的一些參數(shù),然后產(chǎn)生另一個(gè)更小元的函數(shù)。
什么是元?元是指函數(shù)參數(shù)的個(gè)數(shù),比如一個(gè)帶有兩個(gè)參數(shù)的函數(shù)被稱(chēng)為二元函數(shù)。
舉個(gè)簡(jiǎn)單的例子:
function add(a, b) { return a + b; } // 執(zhí)行 add 函數(shù),一次傳入兩個(gè)參數(shù)即可 add(1, 2) // 3 // 假設(shè)有一個(gè) partial 函數(shù)可以做到局部應(yīng)用 var addOne = partial(add, 1); addOne(2) // 3
個(gè)人覺(jué)得翻譯成“局部應(yīng)用”或許更貼切些,以下全部使用“局部應(yīng)用”。
柯里化與局部應(yīng)用如果看過(guò)上一篇文章《JavaScript專(zhuān)題之柯里化》,實(shí)際上你會(huì)發(fā)現(xiàn)這個(gè)例子和柯里化太像了,所以?xún)烧叩降资怯惺裁磪^(qū)別呢?
其實(shí)也很明顯:
柯里化是將一個(gè)多參數(shù)函數(shù)轉(zhuǎn)換成多個(gè)單參數(shù)函數(shù),也就是將一個(gè) n 元函數(shù)轉(zhuǎn)換成 n 個(gè)一元函數(shù)。
局部應(yīng)用則是固定一個(gè)函數(shù)的一個(gè)或者多個(gè)參數(shù),也就是將一個(gè) n 元函數(shù)轉(zhuǎn)換成一個(gè) n - x 元函數(shù)。
如果說(shuō)兩者有什么關(guān)系的話,引用 functional-programming-jargon 中的描述就是:
partialCurried functions are automatically partially applied.
我們今天的目的是模仿 underscore 寫(xiě)一個(gè) partial 函數(shù),比起 curry 函數(shù),這個(gè)顯然簡(jiǎn)單了很多。
也許你在想我們可以直接使用 bind 吶,舉個(gè)例子:
function add(a, b) { return a + b; } var addOne = add.bind(null, 1); addOne(2) // 3
然而使用 bind 我們還是改變了 this 指向,我們要寫(xiě)一個(gè)不改變 this 指向的方法。
第一版根據(jù)之前的表述,我們可以嘗試著寫(xiě)出第一版:
// 第一版 // 似曾相識(shí)的代碼 function partial(fn) { var args = [].slice.call(arguments, 1); return function() { var newArgs = args.concat([].slice.call(arguments)); return fn.apply(this, newArgs); }; };
我們來(lái)寫(xiě)個(gè) demo 驗(yàn)證下 this 的指向:
function add(a, b) { return a + b + this.value; } // var addOne = add.bind(null, 1); var addOne = partial(add, 1); var value = 1; var obj = { value: 2, addOne: addOne } obj.addOne(2); // ??? // 使用 bind 時(shí),結(jié)果為 4 // 使用 partial 時(shí),結(jié)果為 5第二版
然而正如 curry 函數(shù)可以使用占位符一樣,我們希望 partial 函數(shù)也可以實(shí)現(xiàn)這個(gè)功能,我們?cè)賮?lái)寫(xiě)第二版:
// 第二版 var _ = {}; function partial(fn) { var args = [].slice.call(arguments, 1); return function() { var position = 0, len = args.length; for(var i = 0; i < len; i++) { args[i] = args[i] === _ ? arguments[position++] : args[i] } while(position < arguments.length) args.push(argumetns[position++]); return fn.apply(this, args); }; };
我們驗(yàn)證一下:
var subtract = function(a, b) { return b - a; }; subFrom20 = partial(subtract, _, 20); subFrom20(5);寫(xiě)在最后
值得注意的是:underscore 和 lodash 都提供了 partial 函數(shù),但只有 lodash 提供了 curry 函數(shù)。
專(zhuān)題系列JavaScript專(zhuān)題系列目錄地址:https://github.com/mqyqingfeng/Blog。
JavaScript專(zhuān)題系列預(yù)計(jì)寫(xiě)二十篇左右,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖、節(jié)流、去重、類(lèi)型判斷、拷貝、最值、扁平、柯里、遞歸、亂序、排序等,特點(diǎn)是研(chao)究(xi) underscore 和 jQuery 的實(shí)現(xiàn)方式。
如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤剑?qǐng)務(wù)必給予指正,十分感謝。如果喜歡或者有所啟發(fā),歡迎 star,對(duì)作者也是一種鼓勵(lì)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/91401.html
摘要:專(zhuān)題系列共計(jì)篇,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖節(jié)流去重類(lèi)型判斷拷貝最值扁平柯里遞歸亂序排序等,特點(diǎn)是研究專(zhuān)題之函數(shù)組合專(zhuān)題系列第十六篇,講解函數(shù)組合,并且使用柯里化和函數(shù)組合實(shí)現(xiàn)模式需求我們需要寫(xiě)一個(gè)函數(shù),輸入,返回。 JavaScript 專(zhuān)題之從零實(shí)現(xiàn) jQuery 的 extend JavaScritp 專(zhuān)題系列第七篇,講解如何從零實(shí)現(xiàn)一個(gè) jQuery 的 ext...
摘要:寫(xiě)在前面專(zhuān)題系列是我寫(xiě)的第二個(gè)系列,第一個(gè)系列是深入系列。專(zhuān)題系列自月日發(fā)布第一篇文章,到月日發(fā)布最后一篇,感謝各位朋友的收藏點(diǎn)贊,鼓勵(lì)指正。 寫(xiě)在前面 JavaScript 專(zhuān)題系列是我寫(xiě)的第二個(gè)系列,第一個(gè)系列是 JavaScript 深入系列。 JavaScript 專(zhuān)題系列共計(jì) 20 篇,主要研究日常開(kāi)發(fā)中一些功能點(diǎn)的實(shí)現(xiàn),比如防抖、節(jié)流、去重、類(lèi)型判斷、拷貝、最值、扁平、柯里...
摘要:前端日?qǐng)?bào)精選理解的專(zhuān)題之偏函數(shù)譯理解事件驅(qū)動(dòng)機(jī)制游戲開(kāi)發(fā)前端面試中的常見(jiàn)的算法問(wèn)題發(fā)布中文前端頁(yè)面?zhèn)鲄⑸袏y產(chǎn)品技術(shù)刊讀基礎(chǔ)系列二之實(shí)現(xiàn)大轉(zhuǎn)盤(pán)抽獎(jiǎng)掘金指南眾成翻譯編程插入排序眾成翻譯源碼講解函數(shù)技術(shù)風(fēng)暴初體驗(yàn)個(gè)人文 2017-08-16 前端日?qǐng)?bào) 精選 理解 JavaScript 的 async/awaitJavaScript專(zhuān)題之偏函數(shù)[譯]理解 Node.js 事件驅(qū)動(dòng)機(jī)制Pokem...
摘要:與最后,使用我們的寫(xiě)的函數(shù)重寫(xiě)下函數(shù)系列系列目錄地址。系列預(yù)計(jì)寫(xiě)八篇左右,重點(diǎn)介紹中的代碼架構(gòu)鏈?zhǔn)秸{(diào)用內(nèi)部函數(shù)模板引擎等內(nèi)容,旨在幫助大家閱讀源碼,以及寫(xiě)出自己的。如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤剑?qǐng)務(wù)必給予指正,十分感謝。 partial 在《 JavaScript 專(zhuān)題之偏函數(shù)》中,我們寫(xiě)了一個(gè) partial 函數(shù),用來(lái)固定函數(shù)的部分參數(shù),實(shí)現(xiàn)代碼如下: // 這是文章中的第一版 fu...
摘要:專(zhuān)題系列第十八篇,講解遞歸和尾遞歸定義程序調(diào)用自身的編程技巧稱(chēng)為遞歸。然而非尾調(diào)用函數(shù),就會(huì)創(chuàng)建多個(gè)執(zhí)行上下文壓入執(zhí)行上下文棧。所以我們只用把階乘函數(shù)改造成一個(gè)尾遞歸形式,就可以避免創(chuàng)建那么多的執(zhí)行上下文。 JavaScript 專(zhuān)題系列第十八篇,講解遞歸和尾遞歸 定義 程序調(diào)用自身的編程技巧稱(chēng)為遞歸(recursion)。 階乘 以階乘為例: function factorial(n...
閱讀 871·2021-10-25 09:45
閱讀 3293·2021-09-22 14:58
閱讀 3854·2021-08-31 09:43
閱讀 918·2019-08-30 15:55
閱讀 921·2019-08-29 13:51
閱讀 1231·2019-08-29 13:02
閱讀 3488·2019-08-29 12:52
閱讀 1963·2019-08-26 13:27