欧美亚洲中文,在线国自产视频,欧洲一区在线观看视频,亚洲综合中文字幕在线观看

      1. <dfn id="rfwes"></dfn>
          <object id="rfwes"></object>
        1. 站長資訊網(wǎng)
          最全最豐富的資訊網(wǎng)站

          javascript為什么用函數(shù)式編程

          原因:1、js的語法是從Scheme這種函數(shù)式編程語言借鑒而來。2、就瀏覽器端而言,隨著各種單頁框架的發(fā)展,客戶端的處理能力不斷提升,越來越多的業(yè)務(wù)邏輯被放到端,從而導(dǎo)致客戶端要維護(hù)的狀態(tài)越來越多;隨之而來的問題是,一不小心就會大量使用依賴于外部變量的函數(shù),這些函數(shù)隨著業(yè)務(wù)邏輯不斷增加,從而導(dǎo)致邏輯分支劇增,狀態(tài)難以追蹤,代碼可讀性差,難以維護(hù),而函數(shù)式編程有著很好的解決方案。

          javascript為什么用函數(shù)式編程

          前端(vue)入門到精通課程:進(jìn)入學(xué)習(xí)
          API 文檔、設(shè)計、調(diào)試、自動化測試一體化協(xié)作工具:點(diǎn)擊使用

          本教程操作環(huán)境:windows7系統(tǒng)、javascript1.8.5版、Dell G3電腦。

          一、什么是函數(shù)式編程?

          函數(shù)式編程(Functional programming),簡稱 FP,并不是什么庫或者框架,與過程式編程(Procedural programming)相對,而是一種編程范式。FP 通過聲明純函數(shù)抽象數(shù)據(jù)的處理,來避免或盡可能減少函數(shù)調(diào)用對于外部狀態(tài)和系統(tǒng)產(chǎn)生的副作用。

          所謂副作用,大抵有改變函數(shù)外系統(tǒng)狀態(tài),向外拋出異常,處理用戶操作,修改入?yún)?,?shù)據(jù)庫查操作,DOM操作等等可能會引起系統(tǒng)錯誤操作。

          二、為什么在 JavaScript 使用函數(shù)式編程思想

          2.1 從語言特性來看

          JavaScript 一開始的語法就是從 Scheme 這種函數(shù)式編程語言借鑒而來。隨著語言標(biāo)準(zhǔn)的推進(jìn),語言本身的功能性不斷豐富,閉包、箭頭函數(shù)、高階函數(shù),數(shù)組迭代等等功能都讓 JavaScript 中實現(xiàn) FP 變得簡單,簡單講幾個特性:

          2.1.1. lambda 表達(dá)式

          lambda 表達(dá)式其實是一個匿名函數(shù),使用箭頭清晰的表示輸入輸出的映射關(guān)系,JavaScript 中使用箭頭函數(shù)來實現(xiàn)。

          const multiply = x => x * x multiply(6) // 36
          登錄后復(fù)制

          2.1.2 高階函數(shù)

          高階( Higher-order )函數(shù)可以接受一個或者多個函數(shù)作為入?yún)?,輸出一個函數(shù)。

          簡單寫兩個例子

          const add = x => y => x + y const add10 = add(10) add10(5) // 15 const compose = (...fns) => x =>  fns.reduce((acc, fn) => fn(acc), x) const a = x => x + 1 const b = x => x + 2 const composedFn = compose(a, b) composedFn(1) // 1 + 1 + 2 = 4
          登錄后復(fù)制

          2.1.3 filter map forEach reduce 迭代

          Array.prototype 下的 filter map forEach reduce 都是高階函數(shù),因為入?yún)⑹莻€函數(shù)。

          const flatten = (arr = []) => arr.reduce(   (acc, val)=> accconcat(Array.isArray(val) ? flatten(val) : val),   [] ) let arr = [1,[ 4, 5 ], 2, 3]; flatten(arr)  // [1, 4, 5, 2, 3]
          登錄后復(fù)制

          2.2 從實際需求角度來看

          就瀏覽器端而言,隨著各種單頁框架的發(fā)展,客戶端的處理能力不斷提升,越來越多的業(yè)務(wù)邏輯被放到端,從而導(dǎo)致客戶端要維護(hù)的狀態(tài)越來越多。隨之而來的問題是,我們一不小心就會大量使用依賴于外部變量的函數(shù),這些函數(shù)隨著業(yè)務(wù)邏輯不斷增加,從而導(dǎo)致邏輯分支劇增,狀態(tài)難以追蹤,代碼可讀性差,難以維護(hù),而 FP 恰恰有著很好的解決方案。

          另外,現(xiàn)在主流的編程語言基本上都引入函數(shù)式編程的特性,即使是以面向?qū)ο笾Q的 java,通過使用 stream + lambda 表達(dá)式,依然可以實踐函數(shù)式編程思想,而 Spring5 更是將 Reactive 作為主要賣點(diǎn),總之 FP 近來很火。

          而 JS 的函數(shù)式編程生態(tài)也在不斷豐富, RxJS, circleJS 等框架在前端產(chǎn)線上的應(yīng)用也越來越廣。

          三、使用函數(shù)式的優(yōu)點(diǎn)

          使用 FP 編程主要有以下幾個優(yōu)點(diǎn):

          • 將數(shù)據(jù)和處理邏輯分離,代碼更加簡潔,模塊化,可讀性好

          • 容易測試,測試環(huán)境容易模擬

          • 邏輯代碼可復(fù)用性強(qiáng)

          四、函數(shù)式編程相關(guān)概念

          函數(shù)式編程的實現(xiàn)主要依賴于:

          • 聲明式編程

          • 純函數(shù)

          • 不可變數(shù)據(jù)

          4.1 聲明式編程

          聲明式編程 Declarative programming 只描述目標(biāo)的性質(zhì),從而抽象出形式邏輯,告訴計算機(jī)需要計算什么而不是如何一步步計算。例如正則、SQL、 FP 等。

          指令式編程 Imperative Programming 告訴計算機(jī)每一步的計算操作

          最簡單的,相同的數(shù)組處理,使用 for 循環(huán)是指令式,用 map 之類的操作是聲明式。使用聲明式編程,簡化了代碼,提高了復(fù)用率,為重構(gòu)留有余地。

          4.2 純函數(shù)

          純函數(shù)簡要概括有兩個特點(diǎn):

          • 函數(shù)的輸出只與輸入有關(guān),相同輸入產(chǎn)生的輸出一致,并不會不依賴外部條件

          • 函數(shù)調(diào)用不會改變函數(shù)域以外的狀態(tài)或者變量,不會對系統(tǒng)產(chǎn)生副作用

          看個簡單的例子:

          let counter = 0 const increment = () => ++counter const increment = counter => ++counter
          登錄后復(fù)制

          前一個函數(shù)每次調(diào)用都會修改外部變量的值,返回值也依賴于外部變量;后一個函數(shù)對于同一輸入值每次返回的結(jié)果都相同,并且不會對外部狀態(tài)造成影響。所以后一個是純函數(shù)。

          為什么要追求函數(shù)的純度,這就涉及到一個稱為引用透明性的概念。

          4.2.1 引用透明性

          純函數(shù)的這種函數(shù)的返回值只依賴于其輸入值的特性,被稱為引用透明性(referential transparency),純函數(shù)都是可以進(jìn)行緩存的。

          const memorize(pureFn) {   const _cache = {}   return (...args) => {     const key = JSON.stringify(args)     return _cache[key] || (_cache[key] = purFu.apply(null, args))   } }
          登錄后復(fù)制

          4.3 Immutable Data

          「可變的全局狀態(tài)是萬惡之源」(其實從功能代碼的角度看,局部和全局是相對而言的),簡而言之可變狀態(tài)會讓程序的運(yùn)行變得不可預(yù)測,代碼可讀性差,難以維護(hù)。

          在 JS 中,當(dāng)函數(shù)入?yún)⑹菍ο箢愋偷臄?shù)據(jù)時,我們拿到的其實是個引用,所以即使在函數(shù)內(nèi)部我們也是可以修改對象內(nèi)部的屬性,這種情景依然會產(chǎn)生副作用。

          所以這個時候就需要引入 Immutable 的概念。 Immutable 即 unchangeable, Immutable data在初始化創(chuàng)建后就不能被修改了,每次對于 Immutable data 的操作都會返回一個新的 Immutable data。 所以并不會對原來的狀態(tài)形成改變(當(dāng)然不是簡單的深拷貝再修改)。

          Immutable 比較流行的 JS 實現(xiàn)有 immutable-js 和 seamless-immutable; 對于 React 黨來說, immutable-js 一點(diǎn)都不陌生, immutable-js 配合 Redux 就是一種很好的 FP 實踐。

          const map1 = Immutable.Map({a:1, b: {d:2}, c:3}); const map2 = map1.set('a', 50); map1 === map2 // false const mapb1 = map1.get('b') const mapb2 = map2.get('b') mapb1===mapb2 // true
          登錄后復(fù)制

          贊(0)
          分享到: 更多 (0)
          網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號