[Javascript] Array.map() 구현하기

꾸개·2023년 12월 21일
0
post-thumbnail

개요


자바스크립트 딥다이브 북스터디 과정에서 array.map함수를 구현해볼 것을 추천했다. 그 이유는 프로토타입의 this바인딩을 익히고 콜백함수를 익히는데 아주 좋은 연습이라고 했다. 그 당시에는 바쁘기도 하고 이해가 잘 안되어 미뤄두었다가 이번 기회에 구현해보려고 한다.


Array.prototype.map()


map메서드는 Array프로토타입의 메서드이다. 즉, Array프로토타입을 갖고있는 값에만 적용할 수 있다. map() 메서드는 배열 내의 모든 요소 각각에 대하여 주어진 함수를 호출한 결과를 모아 새로운 배열을 반환한다. 무엇인가를 반환하기 때문에 값으로 평가되며 이 값은 다른 값으로 할당할 수 있다. 이것이 for문, forEach문과 가장 큰 차이점이라고 할 수 있다.


arr.map(callback(currentValue[, index[, array]])[, thisArg])

MDN 공식문서에 나와있는 map 메서드의 구성이다. currentValue빼고는 모두 생략 가능하다.
currentValue: 처리할 현재 요소
index: 처리할 현재 요소의 인덱스.
array: map()을 호출한 배열.
thisArg: callback을 실행할 때 this로 사용되는 값.

thisArg? 좀 생소한 매개변수였다. 왜 나는 그 동안 이 매개변수를 못봤을까? 답은 화살표 함수에 있다.
화살표함수의 큰 특징 중 하나는 화살표함수의 this는 자신의 상위 프로토타입체인을 바라본다. 화살표함수는 this바인딩이 되어있지 않기 때문이다.

const arr = [1,2,3]
const myMap = arr.map((v) => v + 1)
console.log(myMap) // [2,3,4]

이 코드에서는 thisArg 매개변수가 들어가지 않았다. 왜냐하면 콜백과 화살표함수가 그 역할을 대신하기 때문이다. 콜백함수의 매개변수 currentValuev로 받고 화살표함수(콜백함수)는 외부의 this를 찾는다. 즉 외부의 thisarr이므로 arrcallaback을 실행할 때 this로 사용되는 값을 v로 자동으로 바인딩 시켰다.

항상 해당 메서드를 사용할떄는 화살표함수가 국룰처럼 사용했기 때문에 thisArg가 바인딩 되는지도 몰랐던 것이다. 그렇다면 해당 식을 화살표 함수가 아닌 일반함수를 콜백함수로 사용하면

const arr = [1,2,3]
const myMap = arr.map(function(v){
	return v + this
}, 1)
console.log(myMap) // [2,3,4]

해당 로직으로 바꿀 수 있다.


구현하기


const customMap = function (callback, thisArg) {
  const array = [];
  for (const key in this) {
    if (Number.isInteger(Number(key))) {
      array[key] = callback.bind(thisArg)(this[key], key, this);
    } else {
      console.error("Invalid key type encountered");
      return;
    }
  }
  return array;
};

Array.prototype.customMap = customMap;

console.log([0, 2, 3].customMap((v) => v));
  1. 첫번째 매개변수는 콜백함수를 받아서 순회하면서 어떤 값을 반환할지 정하고 두번째 매개변수는 callback을 실행할 때 this로 사용될 값을 넣어주었다.

  2. 반환될 빈 배열을 array를 선언해준다.

  3. for...in 반복문을 통해 key값을 받는다.

  4. key값은 문자열이기 때문에 숫자로 타입을 변환하고 truethy값일 경우 반복문을 실행한다.

  5. 어처피 순서대로 순환하기 때문에 array[key]에 순서대로 값을 할당한다.

  6. callback매개변수는 함수를 받을 것이기 때문에 함수 객체의 bind메서드를 사용할 수 있다. callback에서 사용될 thisthisArg로 명시적으로 변환한다.

  7. bind가 실행된 후에 this의 매개변수들을 뒤에 그룹연산자로 붙여준다.

  8. this[key]는 map의 첫번째 매개변수로 현재 순회하는 값을 표현한다.

  9. key는 map의 두번째 매개변수로 현재 순회하는 인덱싱을 표현한다.

  10. this는 함수를 호출한 변수를 가리킨다.

  11. Array.prototype프로퍼티에 명시적으로 할당해준다.

  12. 출력해보면 짜자잔


결론


그냥 간단하게 반복문 돌리는거 아니야? 라고 생각했던 나에게 현실은 실전인 것을 깨닫게 해주는 과제였다. bindthis에 대한 이해를 한걸음 나아갈 수 있는 계기가 되었다.

profile
내 꿈은 프론트 왕

0개의 댓글