根據 Wikipedia 的定義,一個函數稱為純函數需要符合下列兩個條件:
這個副作用的觀念相當重要,會產生副作用的函數對我們的影響是
然而我們也不可能都用純函數,因為我們總要對使用者的輸入做反應,對後端的 request 做反應,為此,這種分別在 ngrx/store 切得很清楚,凡是 reducer 函數一定是純函數 pure function, 而會產生副作用的地方,我們都將它們放在 ngrx/effects 中,這樣在大型專案中,我們可以很清楚要怎樣做重構或者測試。
我們來看幾個純函數的例子
function sum(a, b) {
return a + b;
}
sum(2,5);
// will always return 7
Math.sin(0.5)
// will always return 0.4794...
使用外來變數
var discount = 0.8;
function calcPrice(price) {
return price * discount;
}
console.log(calcPrice(100));
// will return 80
// however when discount var change
var discount = 0.9;
console.log(calcPrice(100));
// now will return 90
使用亂數或者目前時間
// random variable
function getValue() {
return Math.random();
}
console.log(getValue());
// will always return different number
// current time
function getTime() {
return new Date().toISOString();
}
console.log(getTime());
// return current time
setTimeout(() => {
console.log(getTime());
}, 1000);
//return another time
最後這個例子更改了可變物件
// javascript mutable object
const person = {name: 'Joe', age: 20, title: 'Engineer'};
function changeTitle(p) {
p.title = 'Manager';
}
changeTitle(person);
console.log(person);
// will be {name: 'Joe', age: 20, title: 'Manager'}
所有例子在 codepen
在 Javascript 中,有些變數型態是不可變的(immutable), 有些是可變的(mutable).
在 Reducer 中為了要保持純函數,我們不能將一個狀態直接更改它的屬性(property),而需要將原狀態拷貝一份,再將新的這一份拷貝的屬性改成新的值。要怎麼做呢?我們下次來談這個部分。