最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JavaScript中的函數(shù)式編程詳解

 更新時(shí)間:2020年08月22日 22:13:19   作者:蔣鵬飛  
這篇文章主要介紹了JavaScript中的函數(shù)式編程詳解,需要的朋友可以參考下

函數(shù)式編程

函數(shù)式編程是一種編程范式,是一種構(gòu)建計(jì)算機(jī)程序結(jié)構(gòu)和元素的風(fēng)格,它把計(jì)算看作是對數(shù)學(xué)函數(shù)的評(píng)估,避免了狀態(tài)的變化和數(shù)據(jù)的可變,與函數(shù)式編程相對的是命令式編程。我們有這樣一個(gè)需求,給數(shù)組的每個(gè)數(shù)字加一:

// 數(shù)組每個(gè)數(shù)字加一, 命令式編程
let arr = [1, 2, 3, 4];
let newArr = [];
for(let i = 0; i < arr.length; i++){
 newArr.push(arr[i] + 1);
}

console.log(newArr); // [2, 3, 4, 5]

這段代碼結(jié)果沒有問題,但是沒法重用。我們換一個(gè)思維,這里面包含的操作其實(shí)就兩個(gè),一個(gè)是遍歷數(shù)組,一個(gè)是成員加一。我們把這兩個(gè)方法拆出來:

// 先拆加一出來
let add1 = x => x +1;

// 然后拆遍歷方法出來,通過遍歷返回一個(gè)操作后的新數(shù)組
// fn是我們需要對每個(gè)數(shù)組想進(jìn)行的操作
let createArr = (arr, fn) => {
 const newArr = [];
 for(let i = 0; i < arr.length; i++){
 newArr.push(fn(arr[i]));
 }

 return newArr;
} 

// 用這兩個(gè)方法來得到我們期望的結(jié)果
const arr = [1, 2, 3, 4];
const newArr = createArr(arr, add1);
console.log(newArr); // [2, 3, 4, 5], 結(jié)果仍然是對的

這樣拆分后,如果我們下次的需求是對數(shù)組每個(gè)元素乘以2,我們只需要寫一個(gè)乘法的方法,然后復(fù)用之前的代碼就行:

let multiply2 = x => x * 2;

// 調(diào)用之前的createArr
const arr2 = [1, 2, 3, 4];
const newArr2 = createArr(arr2, multiply2);
console.log(newArr2); // [2, 4, 6, 8], 結(jié)果是對的

事實(shí)上我們的加一函數(shù)只能加一,也不好復(fù)用,它還可以繼續(xù)拆:

// 先寫一個(gè)通用加法,他接收第一個(gè)加數(shù),返回一個(gè)方法
// 返回的這個(gè)方法接收第二個(gè)加數(shù),第一個(gè)加數(shù)是上層方法的a
// 這樣當(dāng)我們需要計(jì)算1+2是,就是add(1)(2)
let add = (a) => {
 return (b) => {
 return a + b;
 }
}

// 我們也可以將返回的函數(shù)賦給一個(gè)變量,這個(gè)變量也就變成一個(gè)能特定加a的一個(gè)方法
let add1 = add(1);

let res = add1(4); 
console.log(res); // 5

所以函數(shù)式編程就是將程序分解為一些更可重用、更可靠且更易于理解的部分,然后將他們組合起來,形成一個(gè)更易推理的程序整體。

純函數(shù)

純函數(shù)是指一個(gè)函數(shù),如果它的調(diào)用參數(shù)相同,則永遠(yuǎn)返回相同的結(jié)果。它不依賴于程序執(zhí)行期間函數(shù)外部任何狀態(tài)或數(shù)據(jù)的變化,只依賴于其輸入?yún)?shù)。同時(shí)函數(shù)的運(yùn)行也不改變?nèi)魏瓮獠繑?shù)據(jù),它只通過它的返回值與外部通訊。下面這個(gè)函數(shù)就不是純函數(shù),因?yàn)楹瘮?shù)內(nèi)部需要的discount需要從外部獲?。?/p>

let discount = 0.8;
const calPrice = price => price * discount;
let price = calPrice(200); // 160

// 當(dāng)discount變了,calPrice傳同樣額參數(shù),結(jié)果不一樣,所以不純
discount = 0.9;
price = calPrice(200); // 180

要改為純函數(shù)也很簡單,將discount作為參數(shù)傳遞進(jìn)去就行了

const calPrice = (price, discount) => price * discount;

純函數(shù)可以保證代碼的穩(wěn)定性,因?yàn)橄嗤妮斎胗肋h(yuǎn)會(huì)得到相同結(jié)果。不純的函數(shù)可能會(huì)帶來副作用。

函數(shù)副作用

函數(shù)副作用是指調(diào)用函數(shù)時(shí)除了返回函數(shù)值之外,還對主調(diào)用函數(shù)產(chǎn)生附加的影響,比如修改全局變量或者外部變量,或者修改參數(shù)。這可能會(huì)帶來難以查找的問題并降低代碼的可讀性。下面的foo就有副作用,當(dāng)后面有其他地方需要使用a,可能就會(huì)拿到一個(gè)被污染的值

let a = 5;
let foo = () => a = a * 10;
foo();
console.log(a); // 50

除了我們自己寫的函數(shù)有副作用外,一些原生API也可能有副作用,我們寫代碼時(shí)應(yīng)該注意:

我們的目標(biāo)是盡可能的減少副作用,將函數(shù)寫為純函數(shù),下面這個(gè)不純的函數(shù)使用了new Date,每次運(yùn)行結(jié)果不一樣,是不純的:

要給為純函數(shù)可以將依賴注入進(jìn)去,所謂依賴注入就是將不純的部分提取出來作為參數(shù),這樣我們可以讓副作用代碼集中在外部,遠(yuǎn)離核心代碼,保證核心代碼的穩(wěn)定性

// 依賴注入
const foo = (d, log, something) => {
 const dt = d.toISOString();
 return log(`${dt}: ${something}`);
}

const something = 'log content';
const d = new Date();
const log = console.log.bind(console);
foo(d, log, something);

所以減少副作用一般的方法就是:

1. 函數(shù)使用參數(shù)進(jìn)行運(yùn)算,不要修改參數(shù)
2. 函數(shù)內(nèi)部不修改外部變量
3. 運(yùn)算結(jié)果通過返回值返回給外部

可變性和不可變性

  • 可變性:指一個(gè)變量創(chuàng)建以后可以任意修改
  • 不可變性: 指一個(gè)變量被創(chuàng)建后永遠(yuǎn)不會(huì)發(fā)生改變,不可變性是函數(shù)式編程的核心概念

下面是一個(gè)可變的例子:

如果我們一定要修改這個(gè)參數(shù),我們應(yīng)該將這個(gè)參數(shù)進(jìn)行深拷貝后再操作,這樣就不會(huì)修改參數(shù)了:

到此這篇關(guān)于JavaScript中的函數(shù)式編程詳解的文章就介紹到這了,更多相關(guān)js函數(shù)式編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解ES6 中的Object.assign()的用法實(shí)例代碼

    詳解ES6 中的Object.assign()的用法實(shí)例代碼

    這篇文章主要介紹了ES6 Object.assign()的用法及用途,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • bootstrap datetimepicker控件位置異常的解決方法

    bootstrap datetimepicker控件位置異常的解決方法

    這篇文章主要為大家詳細(xì)介紹了bootstrap datetimepicker控件位置異常的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • JavaScript中fromCharCode 和 fromCodePoint 的詳解與應(yīng)用小結(jié)

    JavaScript中fromCharCode 和 fromCodePoint 的詳解與應(yīng)

    本文將詳細(xì)介紹 JavaScript 中的 String.fromCharCode 和 String.fromCodePoint 方法,這兩個(gè)方法能夠幫助開發(fā)者高效地處理字符與編碼之間的轉(zhuǎn)換,理解它們的區(qū)別與應(yīng)用,將讓你的代碼更加靈活和高效,感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • js中同步與異步處理的方法和區(qū)別總結(jié)

    js中同步與異步處理的方法和區(qū)別總結(jié)

    若要在使用ajax請求后處理發(fā)送請求返回的結(jié)果,最好使用同步請求,下面為大家介紹下js中同步與異步處理的方法和區(qū)別,感興趣的朋友不要錯(cuò)過
    2013-12-12
  • JavaScript this 深入理解

    JavaScript this 深入理解

    一直以來,對于JavaScript 中的this的理解都是很模糊的, 特別是對函數(shù)進(jìn)行apply 與 call 調(diào)用。這兩個(gè)操作如果沒有很好的理解 JavaScript中this的概念,會(huì)越搞越迷糊。
    2009-07-07
  • JS原生2048小游戲源碼分享(全網(wǎng)最新)

    JS原生2048小游戲源碼分享(全網(wǎng)最新)

    這篇文章主要介紹了JS原生2048小游戲源碼分享,實(shí)現(xiàn)代碼全部是給予js實(shí)現(xiàn)的,代碼簡單易懂對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • 利用JavaScript判斷瀏覽器類型及版本

    利用JavaScript判斷瀏覽器類型及版本

    瀏覽器對于我們來說,可能是最熟悉的工具了。在我們的產(chǎn)品開發(fā)過程中,經(jīng)常要考慮瀏覽器兼容問題,以適應(yīng)不同的用戶人群,同時(shí)也減少因?yàn)g覽器兼容問題所帶來的服務(wù)量。所以檢測瀏覽器的版本及類型就是很重要的一件事了,下面來一起看看用Javascript如何實(shí)現(xiàn)。
    2016-08-08
  • BootStrap輪播HTML代碼(推薦)

    BootStrap輪播HTML代碼(推薦)

    本文給大家分享bootstrap輪播h tml代碼,代碼簡單易懂非常不錯(cuò),具有參考借鑒,需要的朋友參考下吧
    2016-12-12
  • JavaScript方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    JavaScript方法_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了JavaScript方法,詳細(xì)的介紹了JavaScript幾種函數(shù)定義方式及使用方法,感興趣的小伙伴們可以參考一下
    2017-06-06
  • 微信小程序?qū)崿F(xiàn)列表項(xiàng)上移下移效果

    微信小程序?qū)崿F(xiàn)列表項(xiàng)上移下移效果

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)列表項(xiàng)上移下移效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07

最新評(píng)論

大洼县| 东光县| 宜君县| 武定县| 徐州市| 大英县| 浏阳市| 任丘市| 友谊县| 博乐市| 东明县| 富宁县| 静宁县| 玉田县| 隆安县| 富川| 阜新市| 石柱| 桐梓县| 三台县| 本溪| 顺平县| 普陀区| 西贡区| 宁化县| 平顶山市| 马关县| 云阳县| 重庆市| 方山县| 邯郸市| 扶沟县| 安仁县| 灵武市| 庆云县| 普格县| 手机| 泉州市| 灌阳县| 乌拉特中旗| 布尔津县|