React 6 순수함수
포스트
취소

React 6 순수함수

순수함수

어떤 함수의 실행이 외부에 영향을 끼치지 않는 함수를 뜻합니다

순수함수의 특징

  1. 동일한 입력에 대해서는 항상 동일한 출력을 반환합니다 동일한 인자로 호출시 항상 동일한 값을 반환합니다

  2. 부수효과가 없습니다 함수 내부에서 외부 상태를 변경하지 않으며 외부 상태에 영향을 주지 않고 외부 변수를 의존하지도 않습니다

  3. 순수함수는 예측 가능합니다 함수의 결과는 오롯이 인자의 의해서만 결정이 됨으로 예측이 가능합니다

순수함수

1
2
3
4
5
6
const addFunction = (x , y) => x + y;

console.log( addFunction(1,2)) /*3*/
console.log(addFunction(2,3))  /*5*/
console.log(addFunction(1,2))  /*3*/

지금 보는 addFunction 은 인자 두개를 받아서 그 인자의 합을 return 하는 함수입니다 이 함수는 순수함수가 맞습니다 순수 함수의 조건중 동일한 입력에 대해서는 동일한 출력을 반환 부수 효과가 없습니다

순수함수 일까?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const addFunction = (x , y) => {

    array_number.push(x + y)

    return x + y;
}

console.log(array_number)
console.log( addFunction(1,2))
console.log(addFunction(2,3))
console.log(addFunction(1,2))
console.log(array_number)

이떄 addFunction 은 순수 함수가 아닙니다 인자를 받아서 두 인자를 더한 값을 return 하는 것은 맞지만 중간에 외부 변수의 의존상태가 들어가 있습니다 순수함수의 조건중 하나는 함수 내부에서 외부 상태를 변경하지 않아야 하는데 지금은 array_number 라는 배열에 값을 입력하고 있습니다 이는 순수함수가 아닙니다

순수함수 Arrays 의 filter , map , reduce

친절하게도 자바스크립트는 Arrays 안에 filter , map , reduce 라는 함수를 만들어 놓았는데 이들의 특징은 전부 순수함수입니다

filter

메서드는 주어진 함수의 조건을 만족하는 배열의 모든 요소를 모아서 새로운 배열을 생성합니다. 이 메서드는 배열을 순회하면서 각 요소를 테스트 함수에 전달하고, 테스트 함수가 true를 반환하는 요소들로 이루어진 새로운 배열을 반환합니다.

1
2
3
4
5
6
7
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const get_oddList = (list) => list.filter(x => x % 2 != 0)

console.log(get_oddList(array_number));
console.log(array_number);

위에서 주어진 조건은 배열을 순회하면서 얻은 x 의 값들중 홀수인 값들만 모아서 완전 새로운 함수를 만들어내고 있는 모습입니다

filter 의 로직

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const get_oddList = function(list) {

    let  temp_list = new Array()

    for(let i = 0; i < list.length; i++){
        if(list[i] % 2 != 0){
            temp_list.push(list[i])
        }
    }

    return temp_list;
}

console.log(get_oddList(array_number));
console.log(array_number);

map

이 메서드는 배열 내의 모든 요소에 대해 주어진 함수를 호출하고, 각 호출 결과로 새로운 배열을 생성합니다. map은 기존 배열을 변경하지 않고 새로운 배열을 반환합니다.

1
2
3
4
5
6
7
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const get_double_time_List = (list) => list.map(x => x *2)

console.log(get_double_time_List(array_number));
console.log(array_number);

여기서 모든 요소를 순회 하면서 x의 값을 2배로 늘려서 새로운 배열을 만들어내는 map 함수입니다

map 의 로직

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const get_double_time_List = function(list){

    let temp_array = new Array();

    for(let i = 0; i < list.length; i++){
        temp_array.push(list[i] * 2);
    }

    return temp_array

}

console.log(get_double_time_List(array_number));
console.log(array_number);

reduce

이 메서드는 배열의 각 요소에 대해 주어진 콜백 함수를 실행하고, 하나의 결과값을 생성합니다. reduce는 배열을 순회하면서 콜백 함수를 호출하고, 이전의 결과값과 현재 요소를 인자로 전달하여 누적된 결과값을 생성합니다.

1
2
3
4
5
6
7
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const get_add_total_value = (list) => list.reduce( (cumulative_value, current_value) => cumulative_value + current_value);

console.log(get_add_total_value(array_number));
console.log(array_number);

예를 들어서 어떤 배열의 모든 요소의 합을 반환하는 함수를 만들떄에는 reduce 함수를 사용합니다 reduce 는 기본적으로 2개의 인자를 받는데

첫번째 인자는 누적값을 계속 보관하고 있을 변수입니다 (cumulative_value) 두번째 인자는 순회하는 배열에서 현재 넘어오는 값을 뜻합니다 (current_value) 그리고 함수 호출로 이 readuce 의 동작 형태를 구성합니다 그럼 이 또한 일반 함수로 구현을 하면 다음과 같습니다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const get_add_total_value = (list) => list.reduce( (cumulative_value, current_value) => cumulative_value + current_value);

const get_add_total_value = (list) => list.reduce(function(cumulative_value , current_value , index){

    console.log(cumulative_value , current_value , index)

    return cumulative_value + current_value;
})

const get_add_total_value = function(list) {

    let cumulative_value = list[0];

    for(let i =1; i < list.length; i++){
    
        let current_value = list[i]; 

        cumulative_value += current_value;

    }
    return cumulative_value;
}

console.log(get_add_total_value(array_number));
console.log(array_number);

2가지 버전을 준비했습니다 동일함 함수 get_add_total_value 를 풀어 쓰면 결국은 제일 마지막에 있는 것처럼 reduce 는 동작을 할것입니다 그리고 기본적으로 reduce 는 초기 값을 줄 있습니다 만약 초기 값이 없음면 리스트의 첫번째 요소를 초기 값으로 사용을 합니다

초기 값이 있는 reduce

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const array_number = [1 ,2, 3, 4, 5, 6, 7, 8, 9, 10]

const get_add_total_value = (list , initial_value) => list.reduce( (cumulative_value, current_value) => {return cumulative_value + current_value} , initial_value);

const get_add_total_value = (list , initial_value) => list.reduce(function(cumulative_value , current_value , index){

    console.log("initial_value" , initial_value)
    console.log(cumulative_value , current_value , index)
   
    return cumulative_value + current_value;

} , initial_value)

const get_add_total_value = function(list , initial_value) {

    let cumulative_value = list[0] + initial_value;

    for(let i =1; i < list.length; i++){

        let current_value = list[i];

        cumulative_value += current_value;

    }
    return cumulative_value;
}

console.log(get_add_total_value(array_number , 10));
console.log(array_number);

초기값이 있는 경우는 다음과 같이 하나의 인자 initial_value 가 추가 되며 각 위치에 포함이 됩니다 그러면 reduce 함수는 이 초기값을 가지고 가며 시작을 하게 됩니다

오늘은 순수 함수를 배워보면서 Arrays 에서 지원하는 몇가지 함수를 살펴보았는데 물론 이들의 기본적인 동작 원리는 순수함수가 맞습니다만 사용하는 방식에 따라서 reduce 는 콜백함수를 호출하기에 외부 환경에 영향을 줄 수도 있습니다