什麼是 Pure Function
一個函數的回傳的結果只依賴於它的參數,並且在執行過程中沒有副作用,可稱其為純函數 pure funciton。
pure function 定義整理如下:
- 函數回傳結果只依賴於它的參數。
- 函數執行過程中沒有副作用。
函數回傳的結果僅依賴於它的參數
const a = 1
const foo = (b) => a + b
foo(2) // => 3 但這邊的 foo 並不是純函數
但 foo
並不是純函數,因它返回的結果依賴於外部變量 a,在不知道 a 的情況下,不能保證 foo(2) 的回傳值是 3。
const a = 1
const foo = (x, b) => x + b
foo(1, 2) // => 3
只要 foo
的程式碼不變,你傳入的參數是確定的,那麼 foo(1, 2) 的值是可預料的。這就是純函數的第一個條件。
函數執行過程沒有副作用
什麼是副作用?
一個函數執行的過程,產生外部可觀察的變化,那麼這個函數就是有副作用的。
以下是純函數
const a = 1
const foo = (obj, b) => {
return obj.x + b
}
const counter = { x: 1 }
foo(counter, 2) // => 3
counter.x // => 1
修改後便不是 純函數
因為內部加了一句 obj.x = 2
,計算前 counter.x
是 1,計算後 counter.x
是 2。
foo
函數因為執行外部的 counter
產生了影響,產生了 副作用,因為它修改了外部傳進來的 object,現在不是純函數。
const a = 1
const foo = (obj, b) => {
obj.x = 2
return obj.x + b
}
const counter = { x: 1 }
foo(counter, 2) // => 4
counter.x // => 2
但修改函數內部變數的值,不是副作用
雖然修改了 obj,但 obj 是內部變量,外部程式觀察不到,故不會產生外部可觀察的變化,所以沒有副作用,因此是一個純函數。
const foo = (b) => {
const obj = { x: 1 }
obj.x = 2
return obj.x + b
}
其他產生副作用的情況
- 呼叫 DOM API 修改頁面。
- 發送 Ajax 請求。
- 呼叫 window.reload 重新渲染畫面。
console.log
印出數據。
以上都會產生外部可觀察的變化,都是副作用。
總結
為何要建立純函數,因為不用擔心純函數會影響外部,出現不可預料的行為。