
map,reduce,forEach 등등 메서드를 사용하면서 함수 내에 입력하는 콜백함수에 인자를 전달하는 방법에 대해 궁금해졌다.
아래 예시의 map과 같이 콜백함수를 전달받는 메서드에 콜백함수를 입력할 때, number,index와 같은 인자는 어떻게 전달되는 걸까?
const a = [1,2,3].map((number,index)=>number + index);
console.log(a); // [1,3,5];
우선 map에 입력한 콜백함수에 전달되는 인자는 map을 정의하는 과정에서 결정된다.
map 메서드를 customMap이란 이름으로 직접 구현해보았다.
const customMap=(array,callback)=>{
const newArray=[];
for (let i=0;i<array.length;i++) {
newArray.push(callback(array[i],i));
}
return newArray;
}
const result = customMap([1,2,3],(number,index)=>number+index);
console.log(result) // [1,3,5]
이처럼 customMap을 정의할 때, 입력받은 array의 원소 개수만큼 반복하면서 callback함수에 array의 i번째 원소와 i값을 입력한다. 이때, 만약 callback(array[i],i)가 아닌 callback(array[i])만을 설정했다면, customMap의 콜백함수 부분에 (number,index)를 입력해도 index는 undefined이기 때문에 결과는 NaN이 담긴 배열이 된다.
(number,index) 이 부분은 콜백함수에 전달할 인자의 순서에 맞는 이름을 정의하기 위한 플레이스홀더 역할을 한다. number는 callback함수에 전달되는 첫번째 인자가 되고 index는 callback함수에 전달되는 두번째 인자가 되는 것이다.
고차함수의 구현 방법을 이해하기 위해 Array객체를 모방해 customArray객체를 구현해봤다.
class customArray {
constructor(...elements) {
this.elements = [...elements];
}
map(callback) {
const result = [];
for (let i=0;i<this.elements.length;i++) {
result.push(callback(this.elements[i],i));
}
return result;
}
reduce(callback,acc=0) {
let newAcc=acc;
for(let i=0;i<this.elements.length;i++) {
newAcc = callback(newAcc,this.elements[i],i);
}
return newAcc;
}
filter(callback) {
const result=[];
for (let i=0;i<this.elemetns.length;i++) {
if (callback(this.elements[i],i)) result.push(this.elements[i]);
}
return result;
}
const arrayA = new customArray(1,2,3);
console.log(arrayA.map((element,index)=>element+index)); // [1,3,5]
console.log(arrayA.filter((element,index)=>element > 3 && index > 1)); // [5]
console.log(arrayA.reduce((acc,element,index)=>acc+element+index,0)); // 9