相信不少作前端的朋友,對函數式編程或多或少都有據說過,對函數式編程的概念你們也可能都據說過了,本篇文章前面會講一些有關函數式編程的特性和優勢,可是不會佔用太多的內容,畢竟講優勢和特性的文章網上一找一大堆javascript
這篇文章最主要的事情,就是幫助不瞭解的函數式編程的朋友,瞭解函數式編程;瞭解函數式編程的朋友,不知道如何運用,幫你分析運用到實際的項目當中css
從字面的意思就能夠理解,函數在函數式編程當中,是不可或缺的一部分。html
閉包和高階函數的概念網上也是一搜一大堆,這裏不作講解,百度一下,你就知道。前端
這個是函數式編程當中,很經常使用,也是很是須要了解的一部分,函數式編程不少時候,都是須要作惰性計算的,舉個網上常見的🌰:vue
// 我要作2+三、2+4的操做
// 傳統寫法
var a = 2;
var b = 3;
var c = 4;
a + b || a + c
// 函數式寫法
var calc = a => b => a + b
var addA = calc(2)
addA(3) || addA(4)
複製代碼
一句話歸納一下: 在作不一樣的事情的狀況下,多是基於某一個相同的條件java
和惰性計算同樣,這也是函數式編程一個很是重要的一個特色,使用函數式編程去寫的代碼,是不在意外面變量環境的改變,它在意的只有傳參,並且他是不會針對任何外部的變量去作修改,最後它 return
回來的結果,只是針對傳參的一個計算,在舉個🌰:react
// 非函數式
var a = 1;
function calc(){
++a
}
calc()
// 函數式
var a = 1;
function calc(num){
return ++num
}
calc(a)
複製代碼
一句話歸納一下:不要讓你的函數,去影響到外部的變量ios
其實沒有反作用的主要要表達的意思,就是不修改狀態,由於你的函數只作你本身要作的事情css3
一句話歸納一下:百因必有果,你給我傳值,我就給你返回值ajax
函數式編程還有幾個 js
的特性會常常用到,好比函數的 做用域 和 做用域鏈 、this指針 、還有上面提到的 閉包 和 高階函數,這都是在函數式編程當中,很是須要了解的點
這裏最主要是給以前沒有接觸過,或者不瞭解函數式編程的朋友,簡單講一下什麼是函數式編程,講的很糙,可是核心的意思大概已經表達了,有不瞭解的能夠留言,緣分回覆;若是講的不對的地方能夠留言指出
在平常的工做當中,後端給咱們返回的結果,不必定是咱們要的,好比這個時候,咱們要作一個 a_bc
轉換成駝峯 aBc
的變化,若是少的話,好說,一個 if
就搞定,若是存在不少個,不肯定的狀況,可是咱們也要作相似的轉換怎麼辦呢
// 非函數式寫法
if (str === 'a_bc') {
str = 'a_Bc'
}
// 函數式寫法
function strTransform(str) {
return str => str.replace(/_[a-z]{1}/g, m => m.replace('_', '').toLocaleUpperCase())
}
複製代碼
這樣使用起來,就很方便,並且隨時都能用,可能不少朋友會說,這不是常常會使用到的方法嗎,這算函數式嗎?
算不算得根據狀況,若是是你直接修改了傳進來的參數,那不算;若是你是經過傳進來的參數,作了計算後,返回了新的值,那這算,由於你不會修改原數據,這樣也就沒有了反作用
選項卡,使咱們平常工做當中,常常會用到功能,針對選項卡,咱們要作一個 「純」 組件:
非函數式編程的寫法
<!-- vue -->
<template>
<div v-for="(item, index) in arr" @click="switchTab($event, index)">
{{item.name}}
</div>
</template>
<script> export { data: { arr:[] }, mounted: fcuntion() { this.arr = ajaxResult; // ajaxResult 表明的是接口返回的結果 }, methods: { switchTab (e, index) { // 針對當前點擊的處理 } } } </script>
複製代碼
// react
class Tab extends Components{
constructor () {
super()
this.arr = []
this.switchTab.bind(this)
},
componentWillMount () {
this.arr = ajaxResult
},
switchTab(index) {
// 針對當前點擊的處理
},
render () {
var list = this.arr.map((item, index) => <div onClick={e => this.switchTab(e, index)}>{item.name}</div>)
return (
<div>
{list}
</div>
)
}
}
複製代碼
react
好久沒有寫了,這多是一份僞代碼,這兩個代碼要表述的意思,就是一個很普通的選項卡,爲了讓對函數式基本沒什麼瞭解的朋友能快速瞭解個人意思,因此我寫了兩個框架的代碼
函數式編程的寫法
<!-- vue -->
<template>
<div v-for="(item, index) in arr" @click="callback($event, index)">
{{item.name}}
</div>
</template>
<script> export { props: ['arr', 'callback'] } </script>
複製代碼
// react
function tab ({arr, callback}) {
return (
<div> {arr.map((item, index) => <div onClick={e => callback(e, index)>{item.name}</div>)} </div>
)
}
複製代碼
你們會發現使用函數式編程代碼量寫法會少不少,其實呢,真正的狀況下,代碼量並不會少,可能還會多一些,但不會多太多,可是這樣寫很符合函數式編程的思想:「純」 、 沒有反作用、不修改狀態
組件的內部,只會作兩件事,渲染和執行點擊對應按鈕的回調,因此說,在哪裏用,都不重要,只要符合該組件的數據格式,就能夠正常展現
相似這樣的功能,這裏涉及的代碼比較複雜,就不寫了,多寫點理論吧
首先呢,咱們要確認幾個這種需求的特色:
class
或者一個 id
去判斷我要拋到的位置,也不能經過一個 class
或者一個 id
來肯定我是否要從哪裏開始拋這是三個很基本的需求,這樣呢,咱們就要使用到函數式編程的幾個特性:函數、閉包、高階函數、惰性計算、沒有反作用
appendChild
到頁面當中,只是 create
了css3
的 animation
,我建議使用貝塞爾曲線這樣的一個拋物線功能,是一個徹底獨立的,沒有任何依賴性的,只作本身拋物線功能,不考慮是誰讓我拋的
答:不能用好很差來形容,要用是否適合當前的業務場景來形容,針對某些狀況下,函數式編程沒有反作用、並且還乾淨、重點不會影響原數據,保證在互相合做的過程中,不會由於本身的功能而影響到他人
答:和上面的回答同樣,沒有最好,只有最合適,你們從一開始到中級左右的時候,都會產生一個誤區,就是面向對象的寫法很好,很牛逼,比面向過程要好用
其實呢,這是一個很嚴重的誤區,當你們在往上走得時候,就會發現,其實好壞都是針對場景,沒有誰敢說什麼是最好的,假如咱們要作一個專題頁,這時候使用 react
或者 vue
實際上是最爛的方法,或者說什麼我封裝一個選項卡,我寫的怎麼怎麼好,沒那個必要
專題頁的定位,就是一個快速展現給用戶的頁面,咱們要的就是快點展現出來,若是你使用框架,還要經歷框架的初始化,加載框架的資源,你封裝的很是厲害的組件的初始化邏輯,其實這個時候用面向過程,一把梭到底多是更好的方案
固然了,有人會說,如今網絡速度這麼快,那些時間能夠忽略不計,可是你不能說有的人確實環境沒有咱們的環境這麼好,咱們公司還有使用 ios8
系統的用戶呢
我可能不如網上的一些文章,針對函數式編程的理論講的那麼清楚,由於原本這也不是一篇針對函數式編程概念的講解,我是想幫助在不知道函數式編程,或者知道不會用的朋友,真正的作個引路人,讓你們把函數式編程真正的運用到項目當中
反正若是你們真的想把函數式編程運用到項目當中,只要記住函數式編程的特色,合理的運用,不要強行的寫成函數式,就好像問答部分同樣,你們要找到合適的,而不是必須用什麼
每一種好的模式,都有其存在的意義,咱們要去儘可能的瞭解每一種模式爲何要這麼作,這麼作的優點在哪裏
感謝你們能一口氣看到這裏,也許是跳着看的,這都不是重點,只要看了的朋友瞭解了,發現本身的業務場景當中,確實有場景可使用,那說明我這篇文章寫的就有價值了
若是有寫的不許確的地方,或者有須要調整的地方,請你們及時指出,歡迎每個大佬的指點,大家指出個人不足,就是我成長的一步,謝謝
最後和你們說一下,我也整了個公衆號,內容會和掘金同步,固然了,確定是先發掘金的,你們感興趣的能夠關注一下個人公衆號