摘要:在函數(shù)式編程語言中,這一特性可用于構(gòu)造無限列表。學(xué)習(xí)網(wǎng)址,是一個(gè)擁有和函數(shù)的數(shù)據(jù)類型,類似于,但它會(huì)輸出非嵌套形式的結(jié)果在其他函數(shù)式編程語言中,也被稱為,也被稱為和。
原文連接
[TOC]
Arity指函數(shù)的參數(shù)數(shù)量,由 -ary 和 -ity 這兩個(gè)英文后綴拼接而成:
const sum = (a, b) => a + b; const Arity = sum.length; console.log(Arity); // 輸出結(jié)果為 2Higher-Order Functions
高階函數(shù),此類函數(shù)可以接收其他函數(shù)作為參數(shù),也可以返回一個(gè)函數(shù)作為返回值:
const filter = (predFunc, list) => { const results = []; list.forEach((listItem) => { if (predFunc(listItem)) { results.push(listItem); } }); return results; } // filter 這個(gè)函數(shù)就是將一個(gè)函數(shù)作為參數(shù)傳入 // 但這都么有什么,主要是后面is函數(shù)返回一個(gè)函數(shù) const is = (type) => (x) => Object(x) instanceof type; // is這個(gè)函數(shù)就是將一個(gè)函數(shù)作為返回值返回到下面的調(diào)用之中 filter(is(Number), [0, "1", 2, null]); // 上面函數(shù)調(diào)用的結(jié)果是 [0, 2]Partial Application
偏函數(shù),在原函數(shù)的基礎(chǔ)上預(yù)填充(pre-filling)部分參數(shù)并返回的新函數(shù):
// 下面是一個(gè)創(chuàng)建偏函數(shù)的輔助函數(shù),下面函數(shù)將一個(gè)函數(shù)和這個(gè)函數(shù)所需要的除了最后一個(gè)參數(shù)的參數(shù)傳入,返回一個(gè)新的函數(shù),這個(gè)新的函數(shù)的參數(shù)為原函數(shù)的最后一個(gè)參數(shù) const partial = (func, ...args) => (...moreArgs) => func(...args, ...moreArgs); // 寫一個(gè)將三個(gè)數(shù)字相加的函數(shù) const add3 = (a, b, c) => a + b + c; // 預(yù)填充 (add3, 2, 3) 三個(gè)參數(shù),空置最后一個(gè)參數(shù),返回一個(gè)新的函數(shù),重點(diǎn)是返回一個(gè)新的函數(shù) const fivePlus = partial(add3, 2, 3); // (c) => 2 + 3 + c fivePlus(4); // => 9Currying
柯里化,將一個(gè)接收多個(gè)參數(shù)的函數(shù)轉(zhuǎn)化為單參數(shù)函數(shù)的方式,轉(zhuǎn)化后的函數(shù)每次只接收一個(gè)參數(shù),然后返回一個(gè)新函數(shù),新函數(shù)可以繼續(xù)接收參數(shù),直到接收到所有的參數(shù):
const sum = (a, b) => a + b; sum(2, 3); // => 6 const curriedSum = (a) => (b) => a + b; curriedSum(40)(2); // => 42. const add2 = curriedSum(2); // (b) => 2 + b add2(10); // => 12Function Composition
函數(shù)合成,接收多個(gè)函數(shù)作為參數(shù)并返回一個(gè)新函數(shù)的方式,新函數(shù)按照傳入的參數(shù)順序,從右往左依次執(zhí)行,前一個(gè)函數(shù)的返回值是后一個(gè)函數(shù)的輸入值:
const compose = (f, g) => (a) => f(g(a)); const floorAndToString = compose((val) => val.toString(), Math.floor); floorAndToString(121.212121); // => "121"Purity
一個(gè)純函數(shù)需要滿足兩個(gè)條件,第一是函數(shù)的返回值只能由輸入值(函數(shù)接收的參數(shù))決定,也就是說純函數(shù)接收相同的參數(shù)會(huì)返回相同的值;第二是純函數(shù)不會(huì)對(duì)自身作用域之外的運(yùn)行環(huán)境產(chǎn)生副作用(side effects),比如說不會(huì)改變外部環(huán)境中變量的值,這會(huì)被認(rèn)為是不安全的行為:
純函數(shù)示例:
const greet = (name) => "Hi, " + name ; greet("Brianne") // => "Hi, Brianne"Side effects
如果函數(shù)或表達(dá)式與其自身作用域之外的可變數(shù)據(jù)(mutable data)發(fā)生了讀寫操作,那么此時(shí)函數(shù)和表達(dá)式就產(chǎn)生了副作用:
let greeting; const greet = () => greeting = "Hi, " + window.name; // greet() 執(zhí)行時(shí)更改了外部環(huán)境的變量 greet(); // => "Hi, Brianne" // new Date() 是可變數(shù)據(jù) const differentEveryTime = new Date();Point-Free Style
point-free style 是一種不顯式向函數(shù)傳遞參數(shù)的代碼風(fēng)格,通常需要柯里化和高階函數(shù)來實(shí)現(xiàn):
const map = (fn) => (list) => list.map(fn); const add = (a) => (b) => a + b; // Not points-free // numbers 是一個(gè)顯式傳遞的參數(shù) const incrementAll = (numbers) => map(add(1))(numbers); // Points-free // add(1) 的返回值隱式傳遞給了 map,作為 map 的 list 參數(shù) const incrementAll2 = map(add(1));Predicate
斷言,一個(gè)返回布爾值的函數(shù):
const predicate = (a) => a > 2; [1, 2, 3, 4].filter(predicate); // => [3, 4]Constant
常量,初始化后不能再次執(zhí)行賦值操作的數(shù)據(jù)類型:
const five = 5; const john = { name: "John", age: 30 }; // 因?yàn)槌A坎豢勺?,所以下面表達(dá)式一定為 true john.age + five === ({ name: "John", age: 30 }).age + (5);
常量具有 referentially transparent 的特性,也就是說將程序中出現(xiàn)的常量替換為它們實(shí)際的值,并不會(huì)影響程序的結(jié)果。譯者話外:實(shí)際上在 JavaScript 中的 const 所聲明的常量并不是完全穩(wěn)定的,使用 Immutable.js 演示更加恰當(dāng):
// 這里的fromJS(), get()函數(shù)都是immutable.js所提供的方法 const five = fromJS(5); const john = fromJS({name: "John", age: 30}); john.get("age") + five === ({ name: "John", age: 30 }).age + (5);Functor
functor 都擁有 map 函數(shù),并且在執(zhí)行 map 之后會(huì)返回一個(gè)新的 functor:
object.map(x => x) === object; object.map(x => f(g(x))) === object.map(g).map(f);
JavaScript 中最常見的 functor 就是數(shù)組類型的實(shí)例:
[1, 2, 3].map(x => x); // => [1, 2, 3] const f = x => x + 1; const g = x => x * 2; [1, 2, 3].map(x => f(g(x))); // => [3, 5, 7] [1, 2, 3].map(g).map(f); // => [3, 5, 7]Lift
lift 發(fā)生在你將值放入 functor 的時(shí)候,如果你將函數(shù) lift 進(jìn)了 Applicative Functor,那么就可以使用這個(gè)函數(shù)處理傳遞給這個(gè) functor 的值。某些 lift 的實(shí)現(xiàn)擁有 lift 或 liftA2 函數(shù),便于在 functor 上執(zhí)行相關(guān)的函數(shù):
const mult = (a, b) => a * b; const liftedMult = lift(mult); // => this function now works on functors like array liftedMult([1, 2], [3]); // => [3, 6] lift((a, b) => a + b)([1, 2], [3, 4]); // => [4, 5, 5, 6]
lift 一個(gè)單參數(shù)的函數(shù)非常類似于 map 操作:
const increment = (x) => x + 1; lift(increment)([2]); // => [3] [2].map(increment); // => [3]Lambda
匿名函數(shù),本質(zhì)上是一個(gè) value:
function(a){ return a + 1; }; (a) => a + 1; // Lambda 常用語高階函數(shù)中 [1, 2].map((a) => a + 1); // = [2, 3] // Lambda 作為 value 被賦值給變量 let addOne = (a) => a + 1;Lazy evaluation
惰性求值,是一種按需執(zhí)行的求值策略,只有需要某個(gè)值時(shí)才會(huì)執(zhí)行相關(guān)的表達(dá)式。在函數(shù)式編程語言中,這一特性可用于構(gòu)造無限列表。
const rand = function*() { while (true) { yield Math.random(); } } const randIter = rand(); randIter.next().value; // 每次執(zhí)行 next() 函數(shù)都會(huì)返回一個(gè)新的隨機(jī)數(shù) // 有且只有在執(zhí)行 next() 的時(shí)候才會(huì)返回新值 // function* 聲明(function關(guān)鍵字后跟一個(gè)星號(hào))定義一個(gè)generator // (生成器)函數(shù),返回一個(gè)Generator對(duì)象。 // 學(xué)習(xí)網(wǎng)址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/function*Monad
Monad,是一個(gè)擁有 of 和 chain 函數(shù)的數(shù)據(jù)類型,chain 類似于 map,但它會(huì)輸出非嵌套形式的結(jié)果:
["cat,dog", "fish,bird"].chain((a) => a.split(",")) // => ["cat", "dog", "fish", "bird"] ["cat,dog", "fish,bird"].map((a) => a.split(",")) // => [["cat", "dog"], ["fish", "bird"]]
在其他函數(shù)式編程語言中,of 也被稱為 return,chain 也被稱為 flatmap 和 bind。
Isomorphism同構(gòu)轉(zhuǎn)換,相同數(shù)據(jù)下不同結(jié)構(gòu)之間的轉(zhuǎn)換。舉例來說,2D 坐標(biāo)既可以存儲(chǔ)為數(shù)組 [2, 3] 也可以存儲(chǔ)為 { x: 2, y: 3 }:
const pairToCoords = (pair) => ({x: pair[0], y: pair[1]}) const coordsToPair = (coords) => [coords.x, coords.y] coordsToPair(pairToCoords([1, 2])) // => [1, 2] pairToCoords(coordsToPair({x: 1, y: 2})) // => { x: 1, y: 2 }Setoid
Setoid,擁有 equals 函數(shù)的數(shù)據(jù)類型,可用于與其他同類型的數(shù)據(jù)進(jìn)行比較。為 Array 類型添加 equals 函數(shù)使其成為 Setoid:
Array.prototype.equals = (arr) => { const len = this.length if (len !== arr.length) { return false } for (let i = 0; i < len; i++) { if (this[i] !== arr[i]) { return false } } return true } [1, 2].equals([1, 2]) // => true [1, 2].equals([0]) // => falseSemigroup
Semigroup,擁有 concat 函數(shù)的數(shù)據(jù)類型,可以與同類型數(shù)據(jù)進(jìn)行合并:
[1].concat([2]) // => [1, 2]Foldable
Foldable,擁有 reduce 函數(shù)的數(shù)據(jù)類型,可以將 Foldable 的實(shí)例轉(zhuǎn)換為其他數(shù)據(jù)類型:
const sum = (list) => list.reduce((acc, val) => acc + val, 0); sum([1, 2, 3]) // => 6
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/80714.html
摘要:所以我覺得函數(shù)式編程領(lǐng)域更像學(xué)者的領(lǐng)域。函數(shù)式編程的原則是完善的,經(jīng)過了深入的研究和審查,并且可以被驗(yàn)證。函數(shù)式編程是編寫可讀代碼的最有效工具之一可能還有其他。我知道很多函數(shù)式編程編程者會(huì)認(rèn)為形式主義本身有助于學(xué)習(xí)。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson?。 禮ou-Dont-Know-JS》作者 關(guān)于譯者:這是一個(gè)流淌著滬江血液...
摘要:函數(shù)式編程術(shù)語大全函數(shù)式編程有許多優(yōu)點(diǎn),它也越來越流行了。然而,每個(gè)編程范式都有自己獨(dú)特的術(shù)語,函數(shù)式編程也不例外。作用域有兩種類似全局作用域和局部作用域。目前最重要的應(yīng)用場景之一,就是在的握手階段,客戶端服務(wù)端利用算法交換對(duì)稱密鑰。 1、JavaScript 函數(shù)式編程術(shù)語大全 函數(shù)式編程(FP)有許多優(yōu)點(diǎn),它也越來越流行了。然而,每個(gè)編程范式都有自己獨(dú)特的術(shù)語,函數(shù)式編程也不例外。...
摘要:函數(shù)式編程術(shù)語大全函數(shù)式編程有許多優(yōu)點(diǎn),它也越來越流行了。然而,每個(gè)編程范式都有自己獨(dú)特的術(shù)語,函數(shù)式編程也不例外。作用域有兩種類似全局作用域和局部作用域。目前最重要的應(yīng)用場景之一,就是在的握手階段,客戶端服務(wù)端利用算法交換對(duì)稱密鑰。 1、JavaScript 函數(shù)式編程術(shù)語大全 函數(shù)式編程(FP)有許多優(yōu)點(diǎn),它也越來越流行了。然而,每個(gè)編程范式都有自己獨(dú)特的術(shù)語,函數(shù)式編程也不例外。...
摘要:而純函數(shù),主要強(qiáng)調(diào)相同的輸入,多次調(diào)用,輸出也相同且無副作用。對(duì)于組合可能不返回值的函數(shù)很有用在其它的一些地方,也稱為,也稱為,也稱為 參考文檔1 參考文檔2 函數(shù)式編程術(shù)語 高階函數(shù) Higher-Order Functions 以函數(shù)為參數(shù)的函數(shù) 返回一個(gè)函數(shù)的函數(shù) 函數(shù)的元 Arity 比如,一個(gè)帶有兩個(gè)參數(shù)的函數(shù)被稱為二元函數(shù) 惰性求值 Lazy evaluation 是...
摘要:從某些方面來講,這章回顧的函數(shù)知識(shí)并不是針對(duì)函數(shù)式編程者,非函數(shù)式編程者同樣需要了解。什么是函數(shù)針對(duì)函數(shù)式編程,很自然而然的我會(huì)想到從函數(shù)開始。如果你計(jì)劃使用函數(shù)式編程,你應(yīng)該盡可能多地使用函數(shù),而不是程序。指的是一個(gè)函數(shù)聲明的形參數(shù)量。 原文地址:Functional-Light-JS 原文作者:Kyle Simpson - 《You-Dont-Know-JS》作者 關(guān)于譯者:...
閱讀 803·2023-04-26 00:30
閱讀 2712·2021-11-23 09:51
閱讀 1059·2021-11-02 14:38
閱讀 2617·2021-09-07 10:23
閱讀 2257·2021-08-21 14:09
閱讀 1405·2019-08-30 10:57
閱讀 1615·2019-08-29 11:20
閱讀 1163·2019-08-26 13:53