国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript函數(shù)式編程入門經(jīng)典

silvertheo / 3437人閱讀

摘要:函數(shù)式編程的定義函數(shù)是一段可以通過其名稱被調(diào)用的代碼。純函數(shù)大多數(shù)函數(shù)式編程的好處來自于編寫純函數(shù),純函數(shù)是對(duì)給定的輸入返回相同的輸出的函數(shù),并且純函數(shù)不應(yīng)依賴任何外部變量,也不應(yīng)改變?nèi)魏瓮獠孔兞俊?/p>

一個(gè)持續(xù)更新的github筆記,鏈接地址:Front-End-Basics,可以watch,也可以star。

此篇文章的地址:JavaScript函數(shù)式編程入門經(jīng)典

正文開始

什么是函數(shù)式編程?為何它重要? 數(shù)學(xué)中的函數(shù)
f(x) = y
// 一個(gè)函數(shù)f,以x為參數(shù),并返回輸出y

關(guān)鍵點(diǎn):

函數(shù)必須總是接受一個(gè)參數(shù)

函數(shù)必須總是返回一個(gè)值

函數(shù)應(yīng)該依據(jù)接收到的參數(shù)(例如x)而不是外部環(huán)境運(yùn)行

對(duì)于一個(gè)給定的x,只會(huì)輸出唯一的一個(gè)y

函數(shù)式編程技術(shù)主要基于數(shù)學(xué)函數(shù)和它的思想,所以要理解函數(shù)式編程,先了解數(shù)學(xué)函數(shù)是有必要的。

函數(shù)式編程的定義

函數(shù)是一段可以通過其名稱被調(diào)用的代碼。它可以接受參數(shù),并返回值。

與面向?qū)ο缶幊蹋∣bject-oriented programming)和過程式編程(Procedural programming)一樣,函數(shù)式編程(Functional programming)也是一種編程范式。我們能夠以此創(chuàng)建僅依賴輸入就可以完成自身邏輯的函數(shù)。這保證了當(dāng)函數(shù)被多次調(diào)用時(shí)仍然返回相同的結(jié)果(引用透明性)。函數(shù)不會(huì)改變?nèi)魏瓮獠凯h(huán)境的變量,這將產(chǎn)生可緩存的,可測試的代碼庫。

函數(shù)式編程具有以下特征 1、引用透明性

所有的函數(shù)對(duì)于相同的輸入都將返回相同的值,函數(shù)的這一屬性被稱為引用透明性(Referential Transparency)

// 引用透明的例子,函數(shù)identity無論輸入什么,都會(huì)原封不動(dòng)的返回
var identity = (i) => {return i}
替換模型

把一個(gè)引用透明的函數(shù)用于其他函數(shù)調(diào)用之間。

sum(4,5) + identity(1)

根據(jù)引用透明的定義,我們可以把上面的語句換成:

sum(4,5) + 1

該過程被稱為替換模型(Substitution Model),因?yàn)楹瘮?shù)的邏輯不依賴其他全局變量,你可以直接替換函數(shù)的結(jié)果,這與它的值是一樣的。所以,這使得并發(fā)代碼緩存成為可能。

并發(fā)代碼: 并發(fā)運(yùn)行的時(shí)候,如果依賴了全局?jǐn)?shù)據(jù),要保證數(shù)據(jù)一致,必須同步,而且必要時(shí)需要鎖機(jī)制。遵循引用透明的函數(shù)只依賴參數(shù)的輸入,所以可以自由的運(yùn)行。

緩存: 由于函數(shù)會(huì)為給定的輸入返回相同的值,實(shí)際上我們就能緩存它了。比如實(shí)現(xiàn)一個(gè)計(jì)算給定數(shù)值的階乘的函數(shù),我們就可以把每次階乘的結(jié)果緩存下來,下一次直接用,就不用計(jì)算了。比如第一次輸入5,結(jié)果是120,第二次輸入5,我們知道結(jié)果必然是120,所以就可以返回已緩存的值,而不必再計(jì)算一次。

2、聲明式和抽象

函數(shù)式編程主張聲明式編程和編寫抽象的代碼。

比較命令式和聲明式
// 有一個(gè)數(shù)組,要遍歷它并把它打印到控制臺(tái)

/*命令式*/
var array = [1,2,3]
for(var i = 0; i < array.length; i++)
console(array[i]) // 打印 1,2,3

// 命令式編程中,我們精確的告訴程序應(yīng)該“如何”做:獲取數(shù)組的長度,通過數(shù)組的長度循環(huán)數(shù)組,在每一次循環(huán)中用索引獲取每一個(gè)數(shù)組元素,然后打印出來。
// 但是我們的任務(wù)只是打印出數(shù)組的元素。并不是要告訴編譯器要如何實(shí)現(xiàn)一個(gè)遍歷。



/*聲明式*/
var array = [1,2,3]
array.forEach((element) => console.log(element)) // 打印 1,2,3

// 我們使用了一個(gè)處理“如何”做的抽象函數(shù),然后我們就能只關(guān)心做“什么”了
函數(shù)式編程主張以抽象的方式創(chuàng)建函數(shù),例如上文的forEach,這些函數(shù)能夠在代碼的其他部分被重用。
3、純函數(shù)

大多數(shù)函數(shù)式編程的好處來自于編寫純函數(shù),純函數(shù)是對(duì)給定的輸入返回相同的輸出的函數(shù),并且純函數(shù)不應(yīng)依賴任何外部變量,也不應(yīng)改變?nèi)魏瓮獠孔兞俊?/p> 純函數(shù)的好處

純函數(shù)產(chǎn)生容易測試的代碼

純函數(shù)容易寫出合理的代碼

純函數(shù)容易寫出并發(fā)代碼

純函數(shù)總是允許我們并發(fā)的執(zhí)行代碼。因?yàn)榧兒瘮?shù)不會(huì)改變它的環(huán)境,這意味著我們根本不需要擔(dān)心同步問題。

純函數(shù)的輸出結(jié)果可緩存

既然純函數(shù)總是為給定的輸入返回相同的輸出,那么我們就能夠緩存函數(shù)的輸出。

高階函數(shù) 數(shù)據(jù)和數(shù)據(jù)類型

程序作用于數(shù)據(jù),數(shù)據(jù)對(duì)于程序的執(zhí)行很重要。每種編程語言都有數(shù)據(jù)類型。這些數(shù)據(jù)類型能夠存儲(chǔ)數(shù)據(jù)并允許程序作用其中。

JavaScript中函數(shù)是一等公民(First Class Citizens)

當(dāng)一門語言允許函數(shù)作為任何其他數(shù)據(jù)類型使用時(shí),函數(shù)被稱為一等公民。也就是說函數(shù)可被賦值給變量,作為參數(shù)傳遞,也可被其他函數(shù)返回。

函數(shù)作為JavaScript的一種數(shù)據(jù)類型,由于函數(shù)是類似String的數(shù)據(jù)類型,所以我們能把函數(shù)存入一個(gè)變量,能夠作為函數(shù)的參數(shù)進(jìn)行傳遞。所以JavaScript中函數(shù)是一等公民。

高階函數(shù)的定義

接受另一個(gè)函數(shù)作為其參數(shù)的函數(shù)稱為高階函數(shù)(Higher-Order-Function),或者說高階函數(shù)是接受函數(shù)作為參數(shù)并且/或者返回函數(shù)作為輸出的函數(shù)。

抽象和高階函數(shù)

一般而言,高階函數(shù)通常用于抽象通用的問題,換句話說,高階函數(shù)就是定義抽象。

抽象 : 在軟件工程和計(jì)算機(jī)科學(xué)中,抽象是一種管理計(jì)算機(jī)系統(tǒng)復(fù)雜性的技術(shù)。 通過建立一個(gè)人與系統(tǒng)進(jìn)行交互的復(fù)雜程度,把更復(fù)雜的細(xì)節(jié)抑制在當(dāng)前水平之下。簡言之,抽象讓我們專注于預(yù)定的目標(biāo)而無須關(guān)心底層的系統(tǒng)概念。

例如:你在編寫一個(gè)涉及數(shù)值操作的代碼,你不會(huì)對(duì)底層硬件的數(shù)字表現(xiàn)方式到底是16位還是32位整數(shù)有很深的了解,包括這些細(xì)節(jié)在哪里屏蔽。因?yàn)樗鼈儽怀橄蟪鰜砹耍涣粝铝撕唵蔚臄?shù)字給我們使用。
// 用forEach抽象出遍歷數(shù)組的操作
const forEach = (array,fn) => {
  let i;
  for(i=0;i console.log(data)) 
閉包和高階函數(shù)

什么是閉包?簡言之,閉包就是一個(gè)內(nèi)部函數(shù)。什么是內(nèi)部函數(shù)?就是在另一個(gè)函數(shù)內(nèi)部的函數(shù)。

閉包的強(qiáng)大之處在于它對(duì)作用域鏈(或作用域?qū)蛹?jí))的訪問。從技術(shù)上講,閉包有3個(gè)可訪問的作用域。
(1) 在它自身聲明之內(nèi)聲明的變量
(2) 對(duì)全局變量的訪問
(3) 對(duì)外部函數(shù)變量的訪問(關(guān)鍵點(diǎn))

實(shí)例一:假設(shè)你再遍歷一個(gè)來自服務(wù)器的數(shù)組,并發(fā)現(xiàn)數(shù)據(jù)錯(cuò)了。你想調(diào)試一下,看看數(shù)組里面究竟包含了什么。不要用命令式的方法,要用函數(shù)式的方法來實(shí)現(xiàn)。這里就需要一個(gè) tap 函數(shù)。

const tap = (value) => {
  return (fn) => {
    typeof fn === "function" && fn(value)
    console.log(value)
  }
} 

// 沒有調(diào)試之前
forEach(array, data => {
  console.log(data + data)
})

// 在 forEach 中使用 tap 調(diào)試
forEach(array, data => {
  tap(data)(() => {
    console.log(data + data)
  })
})

完成一個(gè)簡單的reduce函數(shù)

const reduce = (array,fn,initialValue) => {
  let accumulator;
  if(initialValue != undefined)
    accumulator = initialValue
  else
    accumulator = array[0]

  if(initialValue === undefined)
    for(let i = 1; i < array.length; i++)
      accumulator = fn(accumulator, array[i])
  else
    for(let value of array)
      accumulator = fn(accumulator,value)
  return accumulator
}

console.log(reduce([1,2,3], (accumulator,value) => accumulator + value))
// 打印出6
柯里化與偏應(yīng)用 一些概念 一元函數(shù)

只接受一個(gè)參數(shù)的函數(shù)稱為一元(unary)函數(shù)。

二元函數(shù)

只接受兩個(gè)參數(shù)的函數(shù)稱為二元(binary)函數(shù)。

變參函數(shù)

變參函數(shù)是接受可變數(shù)量的函數(shù)。

柯里化

柯里化是把一個(gè)多參數(shù)函數(shù)轉(zhuǎn)換為一個(gè)嵌套的一元函數(shù)的過程。

例如

// 一個(gè)多參數(shù)函數(shù)
const add = (x,y) => x + y;
add(2,3)

// 一個(gè)嵌套的一元函數(shù)
const addCurried = x => y => x + y;
addCurried(2)(3)

// 然后我們寫一個(gè)高階函數(shù),把 add 轉(zhuǎn)換成 addCurried 的形式。
const curry = (binaryFn) => {
  return function (firstArg) {
    return function (secondArg) {
      return binaryFn(firstArg,secondArg)
    }
  }
}
let autoCurriedAdd = carry(add)
autoCurriedAdd(2)(3)

上面只是簡單實(shí)現(xiàn)了一個(gè)二元函數(shù)的柯里化,下面我們要實(shí)現(xiàn)一個(gè)更多參數(shù)的函數(shù)的柯里化。

const curry = (fn) => {
  if (typeof fn !== "function") {
    throw Error("No function provided")
  }
  return function curriedFn (...args) {
    // 判斷當(dāng)前接受的參數(shù)是不是小于進(jìn)行柯里化的函數(shù)的參數(shù)個(gè)數(shù)
    if(args.length < fn.length) {
      // 如果小于的話就返回一個(gè)函數(shù)再去接收剩下的參數(shù)
      return function (...argsOther) {
        return curriedFn.apply(null, args.concat(argsOther))
      }
    }else {
      return fn.apply(null,args)
    }
  }
}

 const multiply = (x,y,z) => x * y * z;
 console.log(curry(multiply)(2)(3)(4))

柯里化的應(yīng)用實(shí)例:從數(shù)組中找出含有數(shù)字的元素

let match = curry(function (expr,str) {
  return str.match(expr)
})
let hasNumber = match(/[0-9]+/)

let initFilter = curry(function (fn,array) {
  return array.filter(fn)
})

let findNumberInArray = initFilter(hasNumber)
console.log(findNumberInArray(["aaa", "bb2", "33c", "ffffd", ]))
// 打印 [ "bb2", "33c" ]
偏應(yīng)用

我們上面設(shè)計(jì)的柯里化函數(shù)總是在最后接受一個(gè)數(shù)組,這使得它能接受的參數(shù)列表只能是從最左到最右。

但是有時(shí)候,我們不能按照從左到右的這樣嚴(yán)格傳入?yún)?shù),或者只是想部分地應(yīng)用函數(shù)參數(shù)。這里我們就需要用到偏應(yīng)用這個(gè)概念,它允許開發(fā)者部分地應(yīng)用函數(shù)參數(shù)。

const partial = function (fn, ...partialArgs) {
  return function (...fullArguments) {
    let args = partialArgs
    let arg = 0;
    for(let i = 0; i < args.length && arg < fullArguments.length; i++) {
      if(args[i] === undefined) {
        args[i] = fullArguments[arg++]
      }
    }
    return fn.apply(null,args)
  }
}

偏應(yīng)用的示例:

// 打印某個(gè)格式化的JSON
let prettyPrintJson = partial(JSON.stringify,undefined,null,2)
console.log(prettyPrintJson({name:"fangxu",gender:"male"}))

// 打印出
{
  "name": "fangxu",
  "gender": "male"
}
組合與管道 Unix的理念

每個(gè)程序只做好一件事情,為了完成一項(xiàng)新的任務(wù),重新構(gòu)建要好于在復(fù)雜的舊程序中添加新“屬性”。

每個(gè)程序的輸出應(yīng)該是另一個(gè)尚未可知的程序的輸入。

每一個(gè)基礎(chǔ)函數(shù)都需要接受一個(gè)參數(shù)并返回?cái)?shù)據(jù)。

組合(compose)
const compose = (...fns) => {
  return (value) => reduce(fns.reverse(),(acc,fn) => fn(acc), value)
}

compose 組合的函數(shù),是按照傳入的順序從右到左調(diào)用的。所以傳入的 fns 要先 reverse 一下,然后我們用到了reduce ,reduce 的累加器初始值是 value ,然后會(huì)調(diào)用 (acc,fn) => fn(acc), 依次從 fns 數(shù)組中取出 fn ,將累加器的當(dāng)前值傳入 fn ,即把上一個(gè)函數(shù)的返回值傳遞到下一個(gè)函數(shù)的參數(shù)中。

組合的實(shí)例:

let splitIntoSpace = (str) => str.split(" ")
let count = (array) => array.length
const countWords = composeN(count, splitIntoSpace)
console.log(countWords("make smaller or less in amount"))
// 打印 6
管道/序列

compose 函數(shù)的數(shù)據(jù)流是從右往左的,最右側(cè)的先執(zhí)行。當(dāng)然,我們還可以讓最左側(cè)的函數(shù)先執(zhí)行,最右側(cè)的函數(shù)最后執(zhí)行。這種從左至右處理數(shù)據(jù)流的過程稱為管道(pipeline)或序列(sequence)。

// 跟compose的區(qū)別,只是沒有調(diào)用fns.reverse()
const pipe = (...fns) => (value) => reduce(fns,(acc,fn) => fn(acc),value)
函子 什么是函子(Functor)?

定義:函子是一個(gè)普通對(duì)象(在其它語言中,可能是一個(gè)類),它實(shí)現(xiàn)了map函數(shù),在遍歷每個(gè)對(duì)象值的時(shí)候生成一個(gè)新對(duì)象。

實(shí)現(xiàn)一個(gè)函子

1、簡言之,函子是一個(gè)持有值的容器。而且函子是一個(gè)普通對(duì)象。我們就可以創(chuàng)建一個(gè)容器(也就是對(duì)象),讓它能夠持有任何傳給它的值。

const Container = function (value) {
  this.value = value
}

let testValue = new Container(1)
// => Container {value:1}

我們給 Container 增加一個(gè)靜態(tài)方法,它可以為我們?cè)趧?chuàng)建新的 Containers 時(shí)省略 new 關(guān)鍵字。

Container.of = function (value) {
  return new Container(value)
}

// 現(xiàn)在我們就可以這樣來創(chuàng)建
Container.of(1)
// => Container {value:1}

2、函子需要實(shí)現(xiàn) map 方法,具體的實(shí)現(xiàn)是,map 函數(shù)從 Container 中取出值,傳入的函數(shù)把取出的值作為參數(shù)調(diào)用,并將結(jié)果放回 Container。

為什么需要 map 函數(shù),我們上面實(shí)現(xiàn)的 Container 僅僅是持有了傳給它的值。但是持有值的行為幾乎沒有任何應(yīng)用場景,而 map 函數(shù)發(fā)揮的作用就是,允許我們使用當(dāng)前 Container 持有的值調(diào)用任何函數(shù)。
Container.prototype.map = function (fn) {
  return Container.of(fn(this.value))
}

// 然后我們實(shí)現(xiàn)一個(gè)數(shù)字的 double 操作
let double = (x) => x + x;
Container.of(3).map(double)
// => Container {value: 6}

3、map返回了一傳入函數(shù)的執(zhí)行結(jié)果為值的 Container 實(shí)例,所以我們可以鏈?zhǔn)讲僮鳌?/p>

Container.of(3).map(double).map(double).map(double)
// => Container {value: 24}

通過以上的實(shí)現(xiàn),我們可以發(fā)現(xiàn),函子就是一個(gè)實(shí)現(xiàn)了map契約的對(duì)象。函子是一個(gè)尋求契約的概念,該契約很簡單,就是實(shí)現(xiàn) map 。根據(jù)實(shí)現(xiàn) map 函數(shù)的方式不同,會(huì)產(chǎn)生不同類型的函子,如 MayBe 、 Either

函子可以用來做什么?之前我們用tap函數(shù)來函數(shù)式的解決代碼報(bào)錯(cuò)的調(diào)試問題,如何更加函數(shù)式的處理代碼中的問題,那就需要用到下面我們說的MayBe函子

MayBe 函子

讓我們先寫一個(gè)upperCase函數(shù)來假設(shè)一種場景

let value = "string";
function upperCase(value) {
  // 為了避免報(bào)錯(cuò),我們得寫這么一個(gè)判斷
  if(value != null || value != undefined)
    return value.toUpperCase()
}
upperCase(value)
// => STRING

如上面所示,我們代碼中經(jīng)常需要判斷一些nullundefined的情況。下面我們來看一下MayBe函子的實(shí)現(xiàn)。

// MayBe 跟上面的 Container 很相似
export const MayBe = function (value) {
  this.value = value
}
MayBe.of = function (value) {
  return new MayBe(value)
}
// 多了一個(gè)isNothing
MayBe.prototype.isNoting = function () {
  return this.value === null || this.value === undefined;
}
// 函子必定有 map,但是 map 的實(shí)現(xiàn)方式可能不同
MayBe.prototype.map = function(fn) {
  return this.isNoting()?MayBe.of(null):MayBe.of(fn(this.value))
}

// MayBe應(yīng)用
let value = "string";
MayBe.of(value).map(upperCase)
// => MayBe { value: "STRING" }
let nullValue = null
MayBe.of(nullValue).map(upperCase)
// 不會(huì)報(bào)錯(cuò) MayBe { value: null }
Either 函子
MayBe.of("tony")
  .map(() => undefined)
  .map((x)f => "Mr. " + x)

上面的代碼結(jié)果是 MyaBe {value: null},這只是一個(gè)簡單的例子,我們可以想一下,如果代碼比較復(fù)雜,我們是不知道到底是哪一個(gè)分支在檢查 undefined 和 null 值時(shí)執(zhí)行失敗了。這時(shí)候我們就需要 Either 函子了,它能解決分支拓展問題。

const Nothing = function (value) {
  this.value = value;
}
Nothing.of = function (value) {
  return new Nothing(value)
}
Nothing.prototype.map = function (fn) {
  return this;
}
const Some = function (value) {
  this.value = value;
}
Some.of = function (value) {
  return new Some(value)
}
Some.prototype.map = function (fn) {
  return Some.of(fn(this.value));
}

const Either = {
  Some,
  Nothing
}
Pointed 函子

函子只是一個(gè)實(shí)現(xiàn)了 map 契約的接口。Pointed 函子也是一個(gè)函子的子集,它具有實(shí)現(xiàn)了 of 契約的接口。 我們?cè)?MayBe 和 Either 中也實(shí)現(xiàn)了 of 方法,用來在創(chuàng)建 Container 時(shí)不使用 new 關(guān)鍵字。所以 MayBe 和 Either 都可稱為 Pointed 函子。

ES6 增加了 Array.of, 這使得數(shù)組成為了一個(gè) Pointed 函子。
Monad 函子

MayBe 函子很可能會(huì)出現(xiàn)嵌套,如果出現(xiàn)嵌套后,我們想要繼續(xù)操作真正的value是有困難的。必須深入到 MayBe 內(nèi)部進(jìn)行操作。

let joinExample = MayBe.of(MayBe.of(5));
// => MayBe { value: MayBe { value: 5 } }

// 這個(gè)時(shí)候我們想讓5加上4,需要深入 MayBe 函子內(nèi)部
joinExample.map((insideMayBe) => {
  return insideMayBe.map((value) => value + 4)
})
// => MayBe { value: MayBe { value: 9 } }

我們這時(shí)就可以實(shí)現(xiàn)一個(gè) join 方法來解決這個(gè)問題。

// 如果通過 isNothing 的檢查,就返回自身的 value
MayBe.prototype.join = function () {
  return this.isNoting()? MayBe.of(null) : this.value
}
let joinExample2 = MayBe.of(MayBe.of(5));
// => MayBe { value: MayBe { value: 5 } }

// 這個(gè)時(shí)候我們想讓5加上4就很簡單了。
joinExample2.join().map((value) => value + 4)
// => MayBe { value: 9 }

再延伸一下,我們擴(kuò)展一個(gè) chain 方法。

MayBe.prototype.chain = function (fn) {
  return this.map(fn).join()
}

調(diào)用 chain 后就能把嵌套的 MayBe 展開了。

let joinExample3 = MayBe.of(MayBe.of(5));
// => MayBe { value: MayBe { value: 5 } }


joinExample3.chain((insideMayBe) => {
  return insideMayBe.map((value) => value + 4)
})
// => MayBe { value: 9 }

Monad 其實(shí)就是一個(gè)含有 chain 方法的函子。只有of 和 map 的 MayBe 是一個(gè)函子,含有 chain 的函子是一個(gè) Monad。

總結(jié) JavaScript是函數(shù)式編程語言嗎?

函數(shù)式編程主張函數(shù)必須接受至少一個(gè)參數(shù)并返回一個(gè)值,但是JavaScript允許我們創(chuàng)建一個(gè)不接受參數(shù)并且實(shí)際上什么也不返回的函數(shù)。所以JavaScript不是一種純函數(shù)語言,更像是一種多范式的語言,不過它非常適合函數(shù)式編程范式。

補(bǔ)充 1、純函數(shù)是數(shù)學(xué)函數(shù)
function generateGetNumber() {
  let numberKeeper = {}
  return function (number) {
    return numberKeeper.hasOwnProperty(number) ? 
    number : 
    numberKeeper[number] = number + number
  }
}
const getNumber = generateGetNumber()
getNumber(1)
getNumber(2)
……
getNumber(9)
getNumber(10)

// 此時(shí)numberKeeper為:
{
  1: 2
  2: 4
  3: 6
  4: 8
  5: 10
  6: 12
  7: 14
  8: 16
  9: 18
  10: 20
}

現(xiàn)在我們規(guī)定,getNumber只接受1-10范圍的參數(shù),那么返回值肯定是 numberKeeper 中的某一個(gè) value 。據(jù)此我們分析一下 getNumber ,該函數(shù)接受一個(gè)輸入并為給定的范圍(此處范圍是10)映射輸出。輸入具有強(qiáng)制的、相應(yīng)的輸出,并且也不存在映射兩個(gè)輸出的輸入。

下面我來再看一下數(shù)學(xué)函數(shù)的定義(維基百科)

在數(shù)學(xué)中,函數(shù)是一種輸入集合和可允許的輸出集合之間的關(guān)系,具有如下屬性:每個(gè)輸入都精確地關(guān)聯(lián)一個(gè)輸出。函數(shù)的輸入稱為參數(shù),輸出稱為值。對(duì)于一個(gè)給定的函數(shù),所有被允許的輸入集合稱為該函數(shù)的定義域,而被允許的輸出集合稱為值域。

根據(jù)我們對(duì)于 getNumber 的分析,對(duì)照數(shù)學(xué)函數(shù)的定義,會(huì)發(fā)現(xiàn)完全一致。我們上面的getNumber函數(shù)的定義域是1-10,值域是2,4,6,……18,20

2、實(shí)例

文中所有的概念對(duì)應(yīng)的實(shí)例可以在 https://github.com/qiqihaobenben/learning-functional 獲取,可以打開對(duì)應(yīng)的注釋來實(shí)際執(zhí)行一下。

3、薦書

《JavaScript ES6 函數(shù)式編程入門經(jīng)典》,強(qiáng)烈建議想入門函數(shù)式編程的同學(xué)看一下,書有點(diǎn)老,可以略過工具介紹之類的,關(guān)鍵看其內(nèi)在的思想,最重要的是,這本書很薄,差不多跟一本漫畫書類似。

4、推薦文章(非引用文章)

漫談 JS 函數(shù)式編程(一)

從一道坑人的面試題說函數(shù)式編程

函數(shù)式編程入門教程

函數(shù)式編程的一點(diǎn)實(shí)戰(zhàn)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/104113.html

相關(guān)文章

  • 編程書單:十本Python編程語言的入門書籍

    摘要:本文與大家分享一些編程語言的入門書籍,其中不乏經(jīng)典。全書貫穿的主體是如何思考設(shè)計(jì)開發(fā)的方法,而具體的編程語言,只是提供一個(gè)具體場景方便介紹的媒介。入門入門容易理解而且讀起來幽默風(fēng)趣,對(duì)于編程初學(xué)者和語言新手而言是理想的書籍。 本文與大家分享一些Python編程語言的入門書籍,其中不乏經(jīng)典。我在這里分享的,大部分是這些書的英文版,如果有中文版的我也加上了。有關(guān)書籍的介紹,大部分截取自是官...

    desdik 評(píng)論0 收藏0
  • 如何學(xué)JavaScript

    摘要:書籍如下面向?qū)ο缶幊讨改希L(fēng)格輕松易懂,比較適合初學(xué)者,原型那塊兒講得透徹,種繼承方式呢。還有另一件事情是,比如發(fā)現(xiàn)自己某個(gè)知識(shí)點(diǎn)不太清楚,可以單獨(dú)去百度。 作者:小不了鏈接:https://zhuanlan.zhihu.com/p/...來源:知乎著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。 鑒于時(shí)不時(shí),有同學(xué)私信問我(老姚,下同)怎么學(xué)前端的問題。這里統(tǒng)一回...

    light 評(píng)論0 收藏0
  • 前端資源系列(4)-前端學(xué)習(xí)資源分享&前端面試資源匯總

    摘要:特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 特意對(duì)前端學(xué)習(xí)資源做一個(gè)匯總,方便自己學(xué)習(xí)查閱參考,和好友們共同進(jìn)步。 本以為自己收藏的站點(diǎn)多,可以很快搞定,沒想到一入?yún)R總深似海。還有很多不足&遺漏的地方,歡迎補(bǔ)充。有錯(cuò)誤的地方,還請(qǐng)斧正... 托管: welcome to git,歡迎交流,感謝star 有好友反應(yīng)和斧正,會(huì)及時(shí)更新,平時(shí)業(yè)務(wù)工作時(shí)也會(huì)不定期更...

    princekin 評(píng)論0 收藏0
  • JS筆記

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。異步編程入門的全稱是前端經(jīng)典面試題從輸入到頁面加載發(fā)生了什么這是一篇開發(fā)的科普類文章,涉及到優(yōu)化等多個(gè)方面。 TypeScript 入門教程 從 JavaScript 程序員的角度總結(jié)思考,循序漸進(jìn)的理解 TypeScript。 網(wǎng)絡(luò)基礎(chǔ)知識(shí)之 HTTP 協(xié)議 詳細(xì)介紹 HTT...

    rottengeek 評(píng)論0 收藏0
  • 個(gè)人分享--web前端學(xué)習(xí)資源分享

    摘要:前言月份開始出沒社區(qū),現(xiàn)在差不多月了,按照工作的說法,就是差不多過了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了一般來說,差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議那么今天我就把看過的一些學(xué)習(xí)資源主要是博客,博文推薦分享給大家。 1.前言 6月份開始出沒社區(qū),現(xiàn)在差不多9月了,按照工作的說法,就是差不多過了三個(gè)月的試用期,準(zhǔn)備轉(zhuǎn)正了!一般來說,差不多到了轉(zhuǎn)正的時(shí)候,會(huì)進(jìn)行總結(jié)或者分享會(huì)議!那么今天我就...

    sherlock221 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<