前言
純函數 是一個常見的概念,在日常工作中也經常會遇到,它其實非常簡單,今天我們來了解一下它的好處以及為什么要使用它。
兩個特點
一個函數,如果符合以下兩個特點,那么它就可以稱之為 純函數:
- 對於相同的輸入,永遠得到相同的輸出
- 沒有任何可觀察到的副作用
相同輸入得到相同輸出
我們先來看一個不純的反面典型:
let greeting = 'Hello' function greet (name) { return greeting + ' ' + name } console.log(greet('World')) // Hello World
上面的代碼中,greet('World'),是不是永遠返回 Hello World ? 顯然不是,假如我們修改 greeting 的值,就會影響 greet 函數的輸出。即函數 greet 其實是 依賴外部狀態 的。
那我們做以下修改:
function greet (greeting, name) { return greeting + ' ' + name } console.log(greet('Hi', 'Savo')) // Hi Savo
將 greeting 參數也傳入,這樣對於任何輸入參數,都有與之對應的唯一的輸出參數了,該函數就符合了第一個特點。
沒有副作用
副作用的意思是,這個函數的運行,不會修改外部的狀態。
下面再看反面典型:
const user = {
username: 'savokiss' } let isValid = false function validate (user) { if (user.username.length > 4) { isValid = true } }
可見,執行函數的時候會修改到 isValid 的值(注意:如果你的函數沒有任何返回值,那么它很可能就具有副作用!)
那么我們如何移除這個副作用呢?其實不需要修改外部的 isValid 變量,我們只需要在函數中將驗證的結果 return 出來:
const user = {
username: 'savokiss' } function validate (user) { return user.username.length > 4; } const isValid = validate(user)
這樣 validate 函數就不會修改任何外部的狀態了~
電腦刺綉綉花廠 http://www.szhdn.com 廣州品牌設計公司https://www.houdianzi.com
為什么要用純函數?
你可能聽過 純函數 有不少優點,如果你經手過各種難維護的函數,你就更應該考慮使用 純函數。
可測試性(Testable)
讓我們先用不純的 greet 方法來做單元測試:
// jest 語法 describe('greet', function() { it('shows a greeting', function() { expect(greet('Savo')).toEqual('Hello Savo') }); });
如果我們修改了 greeting 變量為 Hi,上面的測試就會失敗了,這本質上不應該發生。
那我們如果換成純函數版本的 greet ,所有都是那么自然~ 只需要修改單元測試中傳入的參數即可!
可緩存性(Cacheable)
純函數可以根據輸入來做緩存。實現緩存的是一種叫作 memorize 的技術。
下面的代碼來自 vue 源碼:
/** * Create a cached version of a pure function. * 只適用於緩存 接收一個字符串為參數的 fn */ export function cached (fn) { const cache = Object.create(null) return function cachedFn (str) { const hit = cache[str] return hit || (cache[str] = fn(str)) } } /** * Capitalize a string. */ export const capitalize = cached((str) => { return str.charAt(0).toUpperCase() + str.slice(1) })
capitalize 即為緩存后的函數,如果多次調用就會返回緩存后的值,從而節省計算資源,而這一切的前提都建立在傳入 cached 中的那個函數為純函數的基礎上。
可移植性 / 自文檔化(Portable / Self-Documenting)
由於純函數是自給自足的,它需要的東西都在輸入參數中已經聲明,所以它可以任意移植到任何地方。
並且純函數對於自己的依賴是 誠實的,這一點你看它的 形參 就知道啦~正所謂 形參起的好,注釋不用搞~(雙押!)純函數就是這么個正直的小可愛~