純函數(shù)
若一個函數(shù)對相同的輸入,永遠會得到相同的輸出崔兴,并且不會影響該函數(shù)作用域以外的環(huán)境變量彰导,則此函數(shù)稱為純函數(shù)浊闪。
純函數(shù)和非純函數(shù):
// 純函數(shù)
function add(a) {
var b = 0;
return a + b;
}
// 非純函數(shù),依賴外部變量
var b = 0;
function add(a) {
return a + b;
}
// 非純函數(shù)螺戳,依賴系統(tǒng)時間
function now() {
return new Date();
}
// 非純函數(shù)搁宾,依賴隨機數(shù)
function random(){
return Math.random();
}
//非純函數(shù),設(shè)置外部 cookie
function setCookie(){
document.cookie = "name=Porco";
}
純函數(shù)可以做到自給自足倔幼,對測試友好盖腿、沒有外部依賴,既不受外部環(huán)境影響损同,也不會影響外部環(huán)境翩腐。
純函數(shù)的好處顯而易見,但是 js 很難能全部做到純函數(shù)膏燃,因為它存在變量茂卦,你不可能在函數(shù)之間傳遞著變量,還能做到純函數(shù)组哩。更好的做法是將純函數(shù)操作抽象出來等龙,然后提供統(tǒng)一的非純操作入口。
比如 react 的 Virtual DOM 就是這樣的思想伶贰,舉例來說蛛砰,原先我們的每次人為操作都會觸發(fā)綁定事件或者監(jiān)聽,然后直接操作 dom 元素黍衙。對于冒泡事件來說泥畅,一次操作會觸發(fā)多次 dom 渲染。react 將節(jié)點跟操作都抽象了出去琅翻,我們的操作首先修改內(nèi)存中的虛擬dom位仁,其他操作會繼續(xù)操作這個dom,而當我們對dom的操作全部完成之后方椎,一次將全部變更的 dom 節(jié)點重新渲染聂抢。
我們可以通過將函數(shù)一層層提純,提高代碼復用率辩尊、降低測試難度
// 原函數(shù)
function double(a, b) {
var sum = a + b;
var doubleSum = sum * 2;
}
// 提取出兩個純函數(shù) add涛浙、multiplicative,可以通過對單個函數(shù)的測試通過摄欲,確保 double 的正確性
// 事實上轿亮,只要 add、multiplicative 這兩個純函數(shù)通過測試胸墙,double 甚至可以不用測
// 因為 純函數(shù) 和 純函數(shù)的組合我注,得到的依舊是一個純函數(shù)
function add(a, b) {
return a + b;
}
function multiplicative(a, b) {
return a * b;
}
function double(a, b) {
return multiplicative(add(a, b), 2);
}