Array.prototype.reduce 직접 구현해보기

aken·2023년 9월 10일
1

mdn에 나와있는 reduce의 개념은 다음과 같다.

배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환합니다.

즉, 배열의 요소를 순회하여 reducer 함수를 실행하고, 하나의 결과값을 반환한다. 여기서 말하는 reducer 함수는 reduce 메서드에 인수로 넘긴 함수를 의미한다.

매개변수

arr.reduce(reducer[, initialValue])
  1. reducer 함수: 각 요소에 대해 실행하는 함수
    function reducer(accumulator, currentValue, currentIndex, array) {
      	// ...
    	return 결과값
    }
    • accumulator: reducer의 반환값을 누적한다.
    • currentValue: 현재 순회하고 있는 요소
    • currentIndex: 현재 순회하고 있는 요소의 index
    • array: reduce를 호출한 배열
    • cf) React의 reducer는 이 reducer 함수와 하는 일이 비슷하다!
  1. initialValue: reducer를 처음으로 호출 할 때 첫 번째 인수로 넘긴 값
    • initialValue를 제공한 경우, accumulator === initialValue, currentValue === arr[0]
    • initialValue를 제공하지 않은 경우, accumulator === arr[0], currentValue === arr[1]
💡 initialValue를 제공하지 않은 경우 reduce는 첫 번째 요소를 건너뛴다.

설계

  1. 누적한 값을 저장하기 위해 acc 변수를 선언한다.
    a. initialValue 값이 주어진 경우, initialValue
    b. initialValue 값이 주어지지 않은 경우, 배열의 첫 번째 요소
  1. 배열 순회를 시작할 index를 결정하기 위해 startIdx 변수를 선언한다.
    a. initialValue 값이 주어진 경우, 첫 번째 요소부터 순회하므로 0
    b. initialValue 값이 주어지지 않은 경우, 첫 번째 요소는 건너뛰기 때문에 1

  2. 배열을 startIdx부터 순회한다.

  3. reducer 함수의 인수로 누적값(acc), 현재 순회하고 있는 요소(this[idx]), 순회하고 있는 요소의 index(idx), 배열(this)을 넘겨주고, 함수를 실행한다.

  4. 함수를 실행한 결과값을 acc에 재할당한다.

  5. 순회를 마치고 나서 누적값(acc)를 반환한다.

코드

Array.prototype.customReduce = function(reducer, initialValue) {
    let acc = initialValue === undefined ? this[0]: initialValue;
    let startIdx = initialValue === undefined ? 1 : 0;
  
  console.log(acc,startIdx)

    for(let idx = startIdx; idx < this.length; idx++) {
        acc = reducer(acc, this[idx], idx, this);
    }

    return acc;
}

✋ 위 코드에서 this는 어째서 배열을 참조하고 있을까?

답을 알기 위해서 먼저 참조 타입에 대한 개념을 알아야 한다.
객체의 프로퍼티(ex: arr.customReduce)에 접근하면 참조 타입이라는 값을 반환한다.

(base, name, strict)
  • base: 객체 (=arr)
  • name: 프로퍼티 이름 (=customReduce)
  • strict: 엄격 모드인지 아닌지

참조 타입 값에 ()를 붙이면 객체와 메서드에 관련된 모든 정보를 받고, 이 정보를 기반으로 this가 결정된다.
따라서 점(.) 또는 대괄호([])를 이용해 메서드를 호출했을 때 this는 참조 타입의 base에 바인딩되어 메서드를 호출한 주체를 가리키게 된다.

0개의 댓글