搜尋
首頁web前端前端問答javascript為什麼用函數式編程
javascript為什麼用函數式編程Sep 30, 2022 pm 03:10 PM
javascript

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

javascript為什麼用函數式編程

本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。

一、什麼是函數式程式設計?

函數式程式設計(Functional programming),簡稱 FP,並不是什麼函式庫或框架,與過程式程式設計(Procedural programming)相對,而是一種程式設計範式。 FP 透過宣告純函數抽象化資料的處理,來避免或盡可能減少函數呼叫對於外部狀態和系統產生的副作用。

所謂副作用,大抵有改變函數外系統狀態,向外拋出異常,處理用戶操作,修改入參,資料庫查操作,DOM操作等等可能會造成系統錯誤操作。

二、為什麼在JavaScript 使用函數式程式設計想法

#2.1 從語言特性來看

JavaScript 一開始的語法就是從Scheme 這種函數式程式語言借鏡而來。隨著語言標準的推進,語言本身的功能性不斷豐富,閉包、箭頭函數、高階函數,數組迭代等等功能都讓JavaScript 中實現FP 變得簡單,簡單講幾個特性:

2.1.1. lambda 表達式

lambda 表達式其實是匿名函數,使用箭頭清晰的表示輸入輸出的映射關係,JavaScript 中使用箭頭函數來實現。

const multiply = x => x * x
multiply(6) // 36

2.1.2 高階函數

高階( Higher-order )函數可以接受一個或多個函數作為入參,輸出一個函數。

簡單寫兩個例子

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

2.1.3 filter map forEach reduce 迭代

Array.prototype 下的filter map forEach reduce 都是高階函數,因為入參是個函數。

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]

2.2 從實際需求角度來看

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

另外,現在主流的程式語言基本上都引入函數式程式設計的特性,即使是以物件導向著稱的java,透過使用stream lambda 表達式,依然可以實踐函數式程式設計思想,而Spring5 更是將Reactive 作為主要賣點,總之FP 近來很火。

而 JS 的函數式程式設計生態也在不斷豐富, RxJS, circleJS 等框架在前端產線上的應用也越來越廣。

三、使用函數式的優點

使用FP 程式設計主要有以下幾個優點:

  • #將資料和處理邏輯分離,程式碼更簡潔,模組化,可讀性好

  • 容易測試,測試環境容易模擬

  • 邏輯程式碼可重複使用性強

四、函數式程式設計相關概念

函數式程式設計的實作主要依賴:

  • 聲明式程式設計

  • #純函數

  • 不可變資料

4.1 宣告式程式設計

#宣告式程式設計Declarative programming 只描述目標的性質,以便抽像出形式邏輯,告訴計算機需要計算什麼而不是如何一步步計算。例如正規、SQL、 FP 等。

指令式程式設計Imperative Programming 告訴計算機每一步的計算操作

最簡單的,相同的陣列處理,使用for 迴圈是指令式,用map 之類的操作是聲明式。使用聲明式編程,簡化了程式碼,提高了復用率,並為重構留有餘地。

4.2 純函數

#純函數簡單概括有兩個特點:

  • 函數的輸出只與輸入有關,相同輸入產生的輸出一致,並不會不依賴外部條件

  • 函數呼叫不會改變函數域以外的狀態或變量,不會對系統產生副作用

看个简单的例子:

let counter = 0
const increment = () => ++counter
const increment = counter => ++counter

前一个函数每次调用都会修改外部变量的值,返回值也依赖于外部变量;后一个函数对于同一输入值每次返回的结果都相同,并且不会对外部状态造成影响。所以后一个是纯函数。

为什么要追求函数的纯度,这就涉及到一个称为引用透明性的概念。

4.2.1 引用透明性

纯函数的这种函数的返回值只依赖于其输入值的特性,被称为引用透明性(referential transparency),纯函数都是可以进行缓存的。

const memorize(pureFn) {
  const _cache = {}
  return (...args) => {
    const key = JSON.stringify(args)
    return _cache[key] || (_cache[key] = purFu.apply(null, args))
  }
}

4.3 Immutable Data

「可变的全局状态是万恶之源」(其实从功能代码的角度看,局部和全局是相对而言的),简而言之可变状态会让程序的运行变得不可预测,代码可读性差,难以维护。

在 JS 中,当函数入参是对象类型的数据时,我们拿到的其实是个引用,所以即使在函数内部我们也是可以修改对象内部的属性,这种情景依然会产生副作用。

所以这个时候就需要引入 Immutable 的概念。 Immutable 即 unchangeable, Immutable data在初始化创建后就不能被修改了,每次对于 Immutable data 的操作都会返回一个新的 Immutable data。 所以并不会对原来的状态形成改变(当然不是简单的深拷贝再修改)。

Immutable 比较流行的 JS 实现有 immutable-js 和 seamless-immutable; 对于 React 党来说, immutable-js 一点都不陌生, 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

【相关推荐:javascript视频教程编程视频

以上是javascript為什麼用函數式編程的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
2 週前By尊渡假赌尊渡假赌尊渡假赌
倉庫:如何復興隊友
4 週前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒險:如何獲得巨型種子
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具