어서와, 개발은 처음이지?

자바스크립트 Array forEach 본문

Javascript

자바스크립트 Array forEach

오지고지리고알파고포켓몬고 2019. 3. 24. 00:31


이번 글에서는 자바스크립트 Array(배열) 객체의 메서드인 forEach에 대해 작성하겠습니다.


forEach는 for문과 마찬가지로 반복적인 기능을 수행할 때 사용합니다.

하지만 for문처럼 index와 조건식, increase를 정의하지 않아도 callback 함수를 통해 기능을 수행할 수 있습니다.


1. [].forEach(callback, thisArg)


기본적인 forEach의 사용법은 아래와 같습니다.

const arr = [0,1,2,3,4,5,6,7,8,9,10];

arr.forEach(function(element){
    console.log(element); // 0 1 2 3 4 5 6 7 8 9 10
});
// 혹은 arrow 함수 가능
arr.forEach(element => console.log(element));

arr 객체의 요소들이 callback 함수에 순서대로 호출되는 모습을 볼 수 있습니다.


for문에 비해 좀 더 깔끔하고, 직관적입니다.(index가 2씩 증가한다거나 그런 변칙이 없이 arr내 모든 요소들이 callback을 호출하는 것을 알 수 있습니다.)



2. 홀수 배열 만들어보기


forEach는 return이 없습니다. 즉, callback 함수에 의해서 어떤 결과물을 내놓고 싶으면 함수 밖의 변수를 사용해야합니다.

const arr = [0,1,2,3,4,5,6,7,8,9,10];
const oddArray = [];

arr.forEach(function(element){
    if(element%2==1) {
        oddArray.push(element);
    }
});

console.log(oddArray); // [ 1, 3, 5, 7, 9 ]

위와 같은 방법으로 결과물을 만들어낼 수 있지만, 함수 밖 영역의 참조는 예상치 못한 예외 상황을 발생시킬 수 있으므로 scope관리를 잘 해줘야 합니다.


사실 이런 경우에는 map 함수를 사용하는 것이 좋습니다. map 함수는 다음 글에서 알아보겠습니다.



3. callback 함수 인자


forEach의 callback 함수에는 배열의 요소 뿐만아니라 index, 전체 배열을 인자로 사용할 수 있습니다.

const arr = [0,1,2,3,4,5,6,7,8,9,10];

arr.forEach(function(element, index, array){
    console.log(`${array}의 ${index}번째 요소 : ${element}`);
});
/*
0,1,2,3,4,5,6,7,8,9,10의 0번째 요소 : 0
0,1,2,3,4,5,6,7,8,9,10의 1번째 요소 : 1
0,1,2,3,4,5,6,7,8,9,10의 2번째 요소 : 2
0,1,2,3,4,5,6,7,8,9,10의 3번째 요소 : 3
0,1,2,3,4,5,6,7,8,9,10의 4번째 요소 : 4
0,1,2,3,4,5,6,7,8,9,10의 5번째 요소 : 5
0,1,2,3,4,5,6,7,8,9,10의 6번째 요소 : 6
0,1,2,3,4,5,6,7,8,9,10의 7번째 요소 : 7
0,1,2,3,4,5,6,7,8,9,10의 8번째 요소 : 8
0,1,2,3,4,5,6,7,8,9,10의 9번째 요소 : 9
0,1,2,3,4,5,6,7,8,9,10의 10번째 요소 : 10
*/

dom 객체에 onclick을 지정할 때 index를 사용하여 arr의 값을 참조하는 방식으로도 사용할 수 있겠습니다.


순수 HTML에서는 dom 객체를 불러오고, onclick을 작성하고, 다시 삽입하는(innerHTML)등의 과정이 복잡하기 때문에 위 방식이 크게 와닿지 않지만,

react에서는 map함수와 index를 사용하여 컴포넌트에 이벤트를 넣는 패턴이 꽤 많으니 인지만 하고 넘어가셔도 괜찮습니다.




4. thisArg


1번의 제목에서 잠깐 언급됐지만 forEach는 callback 함수 이외에 thisArg라는 객체(Object) 인자도 사용할 수 있습니다.


Mozilla 문서에는 아래와 같은 예제가 나와있습니다.

function Counter() {
  this.sum = 0;
  this.count = 0;
}
Counter.prototype.add = function(array) {
  array.forEach(function(entry) {
    this.sum += entry;
    ++this.count;
  }, this);
  // ^---- 주의
};

var obj = new Counter();
obj.add([2, 5, 9]);
obj.count
// 3
obj.sum
// 16


이게 무슨 소리지..?


자바스크립트의 끝판대장 격인 prototype에 대한 개념을 알고 계신분은 forEach 문법을 보러 이 글을 읽고 계시지 않으리라 생각합니다.


thisArg의 핵심을 간단하게 풀면 아래와 같습니다.

const arr = [0,1,2,3,4,5,6,7,8,9,10];
const obj1 = {name: "kim"};
const obj2 = {name: "park"};

arr.forEach(function(element){
    console.log(`${this.name} - ${element}`);
}, obj1);
/*
kim - 0
kim - 1
kim - 2
kim - 3
kim - 4
kim - 5
kim - 6
kim - 7
kim - 8
kim - 9
kim - 10
*/
arr.forEach(function(element){
    console.log(`${this.name} - ${element}`);
}, obj2);
/*
park - 0
park - 1
park - 2
park - 3
park - 4
park - 5
park - 6
park - 7
park - 8
park - 9
park - 10
*/

즉, forEach의 callback에서 this에 대한 참조를 사용할 수 있는데, thisArg가 callback의 this가 되는 것 입니다.

forEach(elem => console.log(this.name + elem), obj)에서 this가 elem => console.log(obj.name + elem)와 같아진다는 뜻 입니다.


근데 이런 문법을 어디다 적용해야 되는거야?



5. 유의할 점


for문은 continue나 break로 반복을 제어할 수 있지만 forEach는 throw(예외)를 발생시키지 않으면 중간에 반복을 종료할 수 없습니다.


만약 조건을 만족할 때 까지만 반복시켜야 한다면 기존 for문이나 every같은 함수를 사용하셔야 합니다.


이상으로 forEach에 대한 글을 마치겠습니다.




2 Comments
댓글쓰기 폼