순수 함수

무제·2021년 8월 10일
1
post-thumbnail

순수 함수


순수 함수 란 똑같은 인자들을 함수의 인자에 넣었을 때 항상 똑같은 결괏값을 리턴하는 함수이다.

또한 부수 효과(side effect)가 없다. 여기서 부수 효과가 무엇일까 ?

부수효과

부수효과 란 함수 내부와 외부가 서로 상호작용 하는 것을 말한다. 예를 들면, 함수 내부에서 함수 외부에 있는 변수의 값을 재할당한다거나 외부의 함수를 함수 내부에서 호출하는 것이다.

const temp_num = 5;
function sum (a, b) {
	return a + b + temp_num;
}

위의 함수는 같은 인자가 들어왔을 때 항상 같은 값을 리턴하기에 순수 함수가 맞을까 ?
정답은 아니다. 함수 내부에서 함수 외부의 변수에 의존하기 때문이다.

또 다른 예시를 보면

const me = {
  name: "맹구",
  hobby: "돌 줍기",
  canSmile: true 
}

function change () {
  me.canSmile = false;
  return me;
}

change();

위의 함수도 항상 똑같은 값을 리턴 할 것이다.
그러나 이 함수는 인자를 받지도 않으며, 함수 외부의 me 라는 객체의 프로퍼티의 값을 재할당 하기에 순수함수라고 볼 수 없다.

function sum_2(num) {
 return num * 2;
}

위의 함수는 순수 함수일까 ?
정답은 맞다. 함수가 외부의 input에 의존하지도 않고, 어떠한 데이터도 변하게 하지 않는다. 고로 부수 효과가 존재하지 않는 순수 함수이다. 또한 같은 인자가 들어왔을 때 항상 같은 값을 리턴하기도 한다.

const multiply_random_number = (num) => Math.random() * num;

multiply_random_number(10);

위의 함수는 순수 함수가 아니다. 매 실행시마다 다른 결과 값을 리턴하기 때문이다.

불변성

순수함수는 인자를 변경 불가능한 데이터로 취급한다.

자바스크립트에서 객체, 배열, 함수는 참조형 자료이다. 참조형 자료는 변수에 값이 아닌 자료가 담겨져 있는 곳의 주소값을 담는다.

let a = [1, 2];
let b = a;
a.push(3);
console.log(a);  // [1, 2, 3];
console.log(b);  // [1, 2, 3];

만약 다른 곳에서 객체의 프로퍼티나 배열의 원소들을 바꾼다면 원본도 바뀐다. 이에 따라, 순수 함수의 성질에 반하게 된다. 그렇다면 어떻게 해야 할까 ?

정답은 바로 불변성이다. 불변성은 변하지 않는다는 의미를 내포하고 있다. 즉, 데이터를 변하지 않게 만드는 것이다. 그렇다면 인자에 들어온 객체나 배열의 원본 데이터를 변경하지 않고 안전하게 사용하려면 어떻게 해야 할까 ?

  1. Array.concat 을 사용
const color = ["red", "cornflower blue", "black"];

function addColor (color_array, color_string) {
  return color_array.concat(color);
}

addColor(color, "white")  // ["red", "cornflower blue", "black", "white"]
console.log(color)  // ["red", "cornflower blue", "black"];
  1. Object.assign 을 사용
const myDog = {
  name: "멍멍이",
  canFight: false,
  cry: true
}

function dog_military (dog) {
  return Object.assign({}, dog, { canFight: true })
}

dog_military(myDog)
/* {
  name: "멍멍이",
  canFight: true,
  cry: true
} */

console.log(myDog) 
/* 
{
  name: "멍멍이",
  canFight: false,
  cry: true
}
*/
  1. Spread Syntax 을 사용
// Array
const color = ["red", "cornflower blue", "black"];

function addColor (color_array, color_string) {
  return [...color_array, color_string];
}

addColor(color, "white")  // ["red", "cornflower blue", "black", "white"]
console.log(color)  // ["red", "cornflower blue", "black"];

// Object
const myDog = {
  name: "멍멍이",
  canFight: false,
  cry: true
}

function dog_military (dog_array) {
  return { ...dog_array, canFight: true };
}

dog_military(myDog)
/* {
  name: "멍멍이",
  canFight: true,
  cry: true
} */

console.log(myDog) 
/* 
{
  name: "멍멍이",
  canFight: false,
  cry: true
}
*/
profile
표현할 수 없는 무제공책

0개의 댓글