배열 메서드용 폴리필: forEach(), map(), filter(), reduce(), find()

글을 안쓴지 오래됐는데 이제서야 올리네요.

Note: if you don't know what polyfills are then please read this article.



각각()



다음은 forEach 작동 방식에 대한 샘플 코드입니다.

const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
  },
  {
    id:2,
    name:'user2',
    isActive: true,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
  }, 
  {
    id:4,
    name:'user4',
    isActive: true,
  }  
]

person.forEach(data=>{
  data.isActive = false;
})

console.log(person)

Output:

[
  { id: 1, name: 'user1', isActive: false },
  { id: 2, name: 'user2', isActive: false },
  { id: 3, name: 'user3', isActive: false },
  { id: 4, name: 'user4', isActive: false }
]



여기서 isActive를 false로 조작하고 있습니다. 그래서 우리는 어떻게 이와 같은 우리 자신의 방법을 만들 수 있습니까? 아래 예를 참조하십시오.

const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
  },
  {
    id:2,
    name:'user2',
    isActive: true,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
  }, 
  {
    id:4,
    name:'user4',
    isActive: true,
  }  
]
Array.prototype.myForEach = function(callback){
  for(let i=0;i<this.length;i++){
    callback(this[i],i, this);
  }
}

person.myForEach(data=>{
  data.isActive = false;
})

console.log(person)

Output:

[
  { id: 1, name: 'user1', isActive: false },
  { id: 2, name: 'user2', isActive: false },
  { id: 3, name: 'user3', isActive: false },
  { id: 4, name: 'user4', isActive: false }
]



위의 예에서 메서드 이름을 myForEach로 지정하고 모든 배열 데이터 구조에서 사용할 수 있도록 배열의 프로토타입에 추가했습니다. 메소드를 추가하면 배열과 함께 (.) 연산자를 사용하여 메소드를 호출하기 때문에 이 키워드를 사용하여 배열을 사용할 수 있습니다. 즉, this의 컨텍스트는 메소드를 호출한 객체가 됩니다.

그리고 위의 예는 forEach()와 동일한 출력을 제공합니다.

지도()




const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
  },
  {
    id:2,
    name:'user2',
    isActive: true,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
  }, 
  {
    id:4,
    name:'user4',
    isActive: true,
  }  
]

const newPerson = person.map(data=>{
  return {...data, isActive:false};
})

console.log(newPerson)



위의 코드에서 우리는 isActive를 false로 만들고 있으며 forEach와 달리 새 배열을 반환합니다. 따라서 출력은 다음과 같을 것입니다.

Output:

[
  { id: 1, name: 'user1', isActive: false },
  { id: 2, name: 'user2', isActive: false },
  { id: 3, name: 'user3', isActive: false },
  { id: 4, name: 'user4', isActive: false }
]



아래는 지도 방법에 대한 polyfill입니다.

Array.prototype.myMap = function(callback){
  const newArray = [];
  for(let i=0;i<this.length;i++){
    newArray.push(callback(this[i],i, this));
  }
  return newArray;
}

const newPerson = person.myMap(data=>{
  return {...data, isActive:false};
})

console.log(newPerson)

Output:

[
  { id: 1, name: 'user1', isActive: false },
  { id: 2, name: 'user2', isActive: false },
  { id: 3, name: 'user3', isActive: false },
  { id: 4, name: 'user4', isActive: false }
]



이것은 forEach와 매우 유사합니다. 차이점은 콜백 함수의 결과로 새 배열을 반환한다는 것입니다. 따라서 출력은 동일합니다.

필터()



isActive 매개변수를 기반으로 사용자를 필터링하는 아래 예를 참조하십시오.

const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
  },
  {
    id:2,
    name:'user2',
    isActive: false,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
  }, 
  {
    id:4,
    name:'user4',
    isActive: false,
  }  
]

const newPerson = person.filter(data=>{
  return data.isActive;
})

console.log(newPerson)

Output:

[
  { id: 1, name: 'user1', isActive: true },
  { id: 3, name: 'user3', isActive: true }
]



맵과 유사하지만 return 문의 조건과 일치하는 항목만 반환합니다. 그래서 그것을 위해 polyfill을 작성합시다

Array.prototype.myFilter = function(callback){
  const newArray = [];
  for(let i=0;i<this.length;i++){
    if(callback.call(this, this[i],i, this)){
      newArray.push(this[i]);
    }
  }
  return newArray;
}
const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
  },
  {
    id:2,
    name:'user2',
    isActive: false,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
  }, 
  {
    id:4,
    name:'user4',
    isActive: false,
  }  
]

const newPerson = person.myFilter(data=>{
  return data.isActive;
})

console.log(newPerson)

Output:

[
  { id: 1, name: 'user1', isActive: true },
  { id: 3, name: 'user3', isActive: true }
]



여기에서는 배열의 컨텍스트를 제공하기 위해 call 메서드를 사용하여 콜백을 호출합니다. 조건이 true가 되면 배열을 푸시하고 조건을 만족하는 항목만 반환합니다.

const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
    balance: 20,
  },
  {
    id:2,
    name:'user2',
    isActive: false,
    balance: 30,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
    balance: 40,
  }, 
  {
    id:4,
    name:'user4',
    isActive: false,
    balance: 50,
  }  
]

const totalBalance = person.reduce((accumulator,data)=>{
  return accumulator+=data.balance;
}, 0)

console.log(totalBalance)

Output:

140



여기에 balance라는 필드를 하나 더 추가했으며, reduce 메서드를 사용하여 합계를 계산할 수 있도록 잔액의 총합을 원합니다. 콜백 함수의 첫 번째 인수는 다를 것이며 초기 값을 0으로 제공했습니다.

아래 예제에서 감소 방법을 위한 폴리필을 살펴보겠습니다.

Array.prototype.myReduce = function(callback, initialValue){
  let accumulator = initialValue===undefined ? undefined: initialValue;
  for(let i=0;i<this.length;i++){
    if(accumulator!==undefined){
      accumulator = callback.call(undefined, accumulator, this[i], i, this)
    }else{
      accumulator = this[i];
    }
  }
  return accumulator;
}
const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
    balance: 20,
  },
  {
    id:2,
    name:'user2',
    isActive: false,
    balance: 30,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
    balance: 40,
  }, 
  {
    id:4,
    name:'user4',
    isActive: false,
    balance: 50,
  }  
]

const totalBalance = person.myReduce((accumulator,data)=>{
  return accumulator+=data.balance;
}, 0)

console.log(totalBalance)

Output

140



여기서 우리는 초기 값인 매개변수를 하나 더 전달하고 있습니다. call 메서드를 사용하여 콜백을 호출하고 그 결과를 accumulator에 할당하여 합계 또는 콜백 함수 내부에 작성한 논리를 얻습니다.

Note: don't forget to provide the initial value otherwise as we can see in the polyfill it will assign this[i] means the whole object and we have to extract the value out of it.



찾다()



find()는 필터 메소드와 매우 유사하지만 여기서는 하나의 결과만 전송합니다.

const foundPerson = person.find(data=>{
  return data.name === 'user1';
})

console.log(foundPerson)

Output:

{ id: 1, name: 'user1', isActive: true, balance: 20 }



하나의 레코드만 반환한다는 출력을 볼 수 있습니다.

Array.prototype.myFind = function(callback, initialValue){
  for(let i=0;i<this.length;i++){
    if(callback.call(accumulator, this[i], i, this)){
      return this[i]
    }
  }
  return accumulator;
}
const person = [
  {
    id:1,
    name:'user1',
    isActive: true,
    balance: 20,
  },
  {
    id:2,
    name:'user2',
    isActive: false,
    balance: 30,
  }, 
  {
    id:3,
    name:'user3',
    isActive: true,
    balance: 40,
  }, 
  {
    id:4,
    name:'user4',
    isActive: false,
    balance: 50,
  }  
]

const foundPerson = person.find(data=>{
  return data.name === 'user1';
})

console.log(foundPerson)

Output

{ id: 1, name: 'user1', isActive: true, balance: 20 }



polyfill에서 조건과 일치하는 레코드를 직접 반환하고 있습니다.

마찬가지로, find와 매우 동일한 findIndex 메소드가 하나 더 있습니다. 이 메소드는 조건과 일치하는 배열 레코드의 인덱스를 반환하여 find polyfill에서 return 문을 return this 대신 return i로 작성할 수 있습니다. i] 및 else 블록에서 -1을 반환할 수 있습니다.

이것이 polyfill에 대한 것입니다. 여기에서 약간의 지식을 얻었기를 바라며 의심이 가는 경우 저에게 의견을 작성해 주시면 기꺼이 해결해 드리겠습니다.

더 많은 폴리필이 추가될 예정입니다. 계속 지켜봐주시고 다음 기사에서 뵙겠습니다!

종료!

좋은 웹페이지 즐겨찾기