Un effet de bord est n'importe quel changement observable à l'extérieur de la fonction, autre que sa valeur de retour.
Des exemples ?
let PI = 3.14;
function area(radius) {
return radius * radius * PI
}
Impures
function area(radius, pi) {
return radius * radius * pi;
}
Pures
function append(array, x) {
array.push(x)
return array;
}
function append(array, x) {
return array.concat([x]);
}
Une fonction, si elle est pure, est :
Une fonction est une valeur, elle peut être assignée, passée en paramètre ou renvoyée en résultat
/* A function is a value and can be assigned */
const double = n => n * 2;
/* Function as parameter */
function mapper(fn) {
/* Function as returned value */
return array => array.map(fn);
}
const doubleArray = mapper(double);
doubleArray([1, 2, 3]); // [2, 4, 6]
const x = {
val: 2
};
const incrementX = () => (x.val += 1);
const doubleX = () => (x.val *= 2);
incrementX();
doubleX();
console.log(x.val); // 6
// Same, but...
const y = {
val: 2
};
const incrementY = () => (y.val += 1);
const doubleY = () => (y.val *= 2);
// ...the order is reversed...
doubleY();
incrementY();
// ... which changes the result
console.log(y.val); // 5
État partagés et mutabilité
const x = {
val: 2
};
const increment = x => ({ ...x, val: x.val + 1 });
const double = x => ({ ...x, val: x.val * 2 });
console.log(double(increment(x)).val); // 6
// No dependency on outside variables,
// no need for a different function for y
const y = {
val: 2
};
// You can call anything, in any order...
increment(y);
double(y);
increment(double(x));
// ... it will not change the result of other calls
console.log(double(increment(x)).val); // 6
Le quoi et non le comment
// Quel est l'age moyen des femmes dans ce groupe ?
const casa = [
{ name: "Le Professeur", gender: "male", age: 43 },
{ name: "Tokyo", gender: "female", age: 28 },
{ name: "Nairobi", gender: "female", age: 32 }
];
function femaleAgeAverage(group) {
let sum = 0;
let femaleCount = 0;
for (let i = 0; i < group.length; i++) {
const member = group[i];
if (member.gender === "female") {
sum += member.age;
femaleCount += 1;
}
}
return sum / femaleCount;
}
Le quoi et non le comment
// Quel est l'age moyen des femmes dans ce groupe ?
const casa = [
{ name: "Le Professeur", gender: "male", age: 43 },
{ name: "Tokyo", gender: "female", age: 28 },
{ name: "Nairobi", gender: "female", age: 32 }
];
const isFemale = p => p.gender === "female";
const getAge = p => p.age;
const sum = a => a.reduce((s, n) => s + n, 0);
const average = a => sum(a) / a.length;
function femaleAgeAverage(group) {
const females = group.filter(isFemale);
const femaleAges = females.map(getAge);
return average(femaleAges);
}
"Quand une fonction se rappelle elle même"
Alors c'est gagné, on peut faire de la récursion !
En pratique
À la fin, c'est souvent élégant