자바스크립트의 객체는 참조에 의한 전달 방식으로 전달된다. 이로 인해 의도치 않게 함수 매개변수로 전달된 원본 객체가 변경되는 side effect가 발생할 수 있다.
함수에 매개변수로 원시 타입과 객체 타입의 인자를 변경해보자.
function changeVal(primitive, obj) {
primitive += 100;
obj.name = 'Kim';
obj.gender = 'female';
}
var num = 100;
var obj = {
name: 'Lee',
gender: 'male'
};
console.log(num); // 100
console.log(obj); // Object {name: 'Lee', gender: 'male'}
changeVal(num, obj);
console.log(num); // 100
console.log(obj); // Object {name: 'Kim', gender: 'female'}
changeVal 함수는 매개변수를 통해 전달받은 원시 타입 인수 num
와 객체 타입 인수 obj
를 함수 몸체에서 변경한다.
원시 타입 인수 :
객체 타입 인수 :
이를 그림으로 표현하면 아래와 같다.
객체가 여러 곳에서 참조된다면 의도치 않은 side effect를 발생시킬 가능성이 높다.
side effect를 줄이기 위해서는 객체를 불변 객체로 만들면 된다. 객체를 불변 객체로 만들면 원시값처럼 객체 상태 변경을 원천봉쇄할 수 있다. 만약 객체의 상태 변경이 필요한 경우 깊은 복사
를 통해 새로운 객체를 생성하고 재할당을 하자.
함수형 프로그래밍에서 순수함수와 비순수함수를 나누는 기준은 side effect 유무이다.
순수함수 예제
var count = 0; // 현재 카운트를 나타내는 상태
// 순수 함수 increase는 동일한 인수가 전달되면 언제나 동일한 값을 반환한다.
function increase(n) {
return ++n;
}
// 순수 함수가 반환한 결과값을 변수에 재할당해서 상태를 변경
count = increase(count);
console.log(count); // 1
count = increase(count);
console.log(count); // 2
비순수함수 예제
var count = 0; // 현재 카운트를 나타내는 상태: increase 함수에 의해 변화한다.
// 비순수 함수
function increase() {
return ++count; // 외부 상태에 의존하며 외부 상태를 변경한다.
}
// 비순수함수는 외부 상태 `count`를 변경하므로 상태 변화를 추적하기 어려워진다.
increase();
console.log(count); // 1
increase();
console.log(count); // 2