當一個函式的輸出結果只受輸入值影響時,意思是函式在相同的輸入值時,需產生相同的輸出,任何改變現存值的賦值(比如 x = x + 1)都是不允許的。
純函式接受一個或一個以上的引數,必定回傳某個值或是另一個函示,而且純函式不會產生任何副作用(Side Effect),例如:設定全域變數、修改應用程式的狀態,或是對函式外部資料的修改等等,也不會改變預期的輸出結果,因為純函示將輸入的引數視為不可變動。
在下方的範例中,有一個名為 addNew 的變數,它是在 add() 函式之外宣告的。但是該變數的狀態在 add() 函式內部又改變了。因此,add() 函式對超出其範圍的變數有副作用,因此被視為不純函數。
var addNew = 0;
function add(a, b) {
addNew = 1;
return a + b + addNew;
}
console.log(add(4, 5)); //10
以物件來說明:
在以下程式碼中,因為 impureAssoc 函式引入 person 物件,又在函式內部做修改,導致 person 這個物件被徹底改變,所以不是純函式。
const impureAssoc = (key, value, object) => {
object[key] = value;
};
const person = {
name: "Lily",
};
impureAssoc("shoeSize", 400, person);
console.log({
person,
result,
}); //{ person: { name: "Lily", shoeSize: 400 }, result: undefined }
我們將第一個例子及第二個例子做修改:
下方的程式碼,無論您在何處何時調用它。輸入值為 2 跟 4 得出的結果永遠會是 6,沒有其他任何東西會影響輸出,輸出結果只受輸入值影響,並且可以預期結果為何。
function add(a, b) {
return a + b;
}
console.log(add(4, 5)); //9
以物件來說下方程式碼,pureAssoc 這個函示一樣引入 person 物件,但用了延展運算子來做出一個副本,再對副本做修改,不會對原本傳進來的物件做修改,這樣 pureAssoc()就是純函式了。
const pureAssoc = (key, value, object) => ({
...object,
[key]: value,
});
const person = {
name: "Lily",
};
const result = pureAssoc("shoeSize", 400, person);
console.log({
person,
result,
}); //{ person: { name: "Lily" }, result: { name: "Lily", shoeSize: 400 } }