함수의 사이드 이펙트
함수의 side effect는 함수를 동작시키면서
함수 외부에서 무언가를 변화시키는 것을 의미한다.
//side effect
//input -> output
const array = [1, 2, 3];
function mutateArray(arr) {
arr.pop();
}
mutateArray(array);
console.log(array);
mutateArray함수는 side effect를 일으킨다.
해당 함수에 인자로 전달된 배열인 array는 함수가 동작하면
pop으로 인해 변화하기 때문이다.
function mutateArray2(arr) {
arr.forEach((item) => {
arr.push(1);
});
}
mutateArray2(array);
console.log(array);
마찬가지로 이 함수 또한 side effect를 불러일으킨다.
이와 같이 함수가 실행될 때 외부의 무언가를 변화시키는 것을
함수의 부작용(side effect)라 한다.
no side effect
function removeLastItem(arr) {
const newArray = [].concat(arr);
newArray.pop();
return newArray;
}
const array2 = removeLastItem(array);
console.log(array, array2);
반면 이 함수는 side effect를 일으키지 않는다.
인자로 받은 배열을 함수 내에서 복사하고 변화시켜 리턴하기 때문에
기존의 array배열은 변화가 일어나지 않는다.
function multiplyBy2(arr) {
return arr.map((item) => item * 2);
}
const array3 = multiplyBy2(array);
console.log(array, array2, array3);
마찬가지로 이 함수 또한 변형된 결과를 리턴하여 다른 변수에 저장할 뿐
기존의 array와 array2에 변화를 일으키지 않는다.
참조 투명성(referential transparency)
참조 투명성은 같은 인자에 대해 같은 결괏값을 리턴하는 것을 의미한다.
side effect가 있을 때 참조 불투명성을 가지고
side effect가 없을 때 참조 투명성을 가지는 상황이 많지만
둘은 다른 개념이기 때문에 항상 그렇지는 않다.
부작용이 있지만 참조 투명성을 가짐
//a is not pure func
function a() {
console.log("hi");
}
a();
함수 a는 화면에 출력을 하기 때문에 side effect를 일으킨다.
a는 언제 어떻게 실행해도 항상 같은 결과를 출력하므로 참조 투명성을 가진다.
부작용이 없고 참조 투명성을 가짐
function b(num1, num2) {
return num1 + num2;
}
b(3, 4); //7, always
함수 b는 어떠한 외부의 상황을 변화시키지 않으므로 side effect가 없는 pure function이다.
또한 같은 인자에 대해 항상 같은 값을 리턴하므로 참조 투명성을 가진다.
참조 투명성?
function c(num) {
return num * 2;
}
c(b(3, 4)); //b의 인자값에 영향을 받음
c(7);
함수 c는 pure function이 맞다.
또한 인자에 따라 항상 같은 값을 리턴하므로 참조 투명성을 가져야 하는 것이 맞다.
하지만 c(b()) === c(b())라고 확신할 수 없는 것은
함수 b를 같은 인자로 전달하더라도 b의 인자에 따라 그 값이 달라지므로
같은 리턴을 보장할 수 없다.
이와 같이 side effect를 가지는 함수는 외부가 변화함에 따라 영향을 받을 수 있다.
좋은 함수
- 하나의 함수는 하나의 task를 실행시킨다.
- return state, 상태를 리턴한다.
- side effect를 최소한 줄이는 순수함수
- 외부와 공유하는 state가 낮을수록 좋다. 결합도가 낮다.
- immutable state, 불변하는 상태를 가진다.
- composable한 함수
- predictable, 참조 투명성을 가져 예측이 가능하다.
'Front-end > JavaScript' 카테고리의 다른 글
JS FP 3편 - 선언형과 명령형(Imperative vs Declarative) (0) | 2023.02.20 |
---|---|
JS FP 2편 - 참조 투명성과 멱등성(Idempotence) (0) | 2023.02.19 |
JS OOP 6편 - 다형성(Polymorphism) (0) | 2023.02.15 |
JS OOP 5편 - Class private 문법(#) (0) | 2023.02.14 |
JS OOP 4편 - extends(JS 클래스 상속) (0) | 2023.02.13 |