분류 javascript

JavaScript Foreach : 초보자를 위한 종합 가이드

컨텐츠 정보

  • 조회 9 (작성일 )

본문

바로 요점! 자바 스크립트에서 forEach는 정확히 무엇이며, 어디에서 왔으며 "배열 형"객체에서 사용하는 방법을 포함하여 사용 사례는 무엇입니까?


이 가이드의 끝에서 이러한 질문에 대한 답을 찾을 수 있습니다.


배열에 대해 잘 알고 있다면 다음을 살펴 보겠습니다.


const lists = ['item1', 'item2', 'item3']



console.log (lists)를 사용하거나 콘솔에 줄을 추가하면 데이터를 얻을 수 있습니다. 그것은 매우 간단합니다.


위의 표기법은 array literal이라고  하며 사용이 매우 간단합니다.


그러나 내부적으로 JavaScript 엔진은 대신 다음과 같이 내장 Array() 생성자 함수를 사용합니다.


const lists = new Array('item1', 'item2', 'item3')


이것은 동등한 객체 표기법입니다.


리터럴 표기법을 위의 표기법으로 바꾸면 콘솔에 동일한 구조가 표시됩니다.


이제 한 단계 더 나아가 이 Array 생성자를 확인하면 여러 메서드로 구성된 프로토 타입 속성을 찾을 수 있습니다. 정말 빨리 살펴 보겠습니다.


Array.prototype을 입력합니다. 콘솔에서 다른 메소드와 함께 forEach를 찾을 수 있습니다.


Array forEach 



그것이 그 근원입니다.


프로토 타입 속성이 OOP에서 작동하는 방식을 알고 있다면 forEach를 포함하여 여기에 정의 된 모든 메서드가 상속되어 개체 인스턴스에서 사용할 수 있습니다. 이 경우 lists 배열입니다.


즉, 다음과 같이 lists 배열에서 직접 호출 할 수 있습니다.


lists.forEach()


그렇다면 ForEach는 정확히 무엇입니까? 


ForEach는 배열을 반복하거나 반복하는 수단 중 하나입니다. 현대 JavaScript에서는 일반적으로 전통적인 for 루프 대신 사용됩니다.


구문을 살펴 보겠습니다.


forEach(callback(currentElement, index, arr), thisValue)


콜백 함수를 인수로 받고 배열의 각 요소에 대해 실행합니다. 이 콜백 함수는 현재 요소 (필수), 인덱스 및 요소가 속한 배열 (예 : arr)의 세 가지 인수를 받습니다.


또한 thisValue 매개 변수 (지정된 경우)는 콜백에서 this의 값으로 사용됩니다.


즉, 실제로 보자!


간단한 for 루프로 시작하여 루프가 어떻게 작동하는지 엿볼 수 있습니다. 이것은 또한 우리에게 재충전의 역할을 할 것입니다.


따라서 기본 .html을 설정하고 .js 파일을 링크하십시오 (또는 편한 경우 브라우저 개발자 도구를 사용하십시오).


.js 파일에 다음 코드를 추가합니다.



const lists = ['item1', , 'item2', 'item3']
const newList = []

for (let i = 0; i < lists.length; i++) {
  newList.push(lists[i]);
}

console.log(newList);


여기에서는 lists 배열을 반복 한 다음 모든 반복 요소를 newList 배열로 푸시합니다.


lists 배열의 빈도가 낮음을 확인하십시오. 우리는 의도적으로 첫 번째와 세 번째 배열 항목 사이의 요소를 정의하지 않습니다. 


파일을 저장하고 콘솔에서 newList를 확인하면 다음 출력이 표시됩니다.


["item1", undefined, "item2", "item3"]



첫 번째 인덱스, 목록 [1] 즉 두 번째 배열 항목에서 정의되지 않은 값을 얻습니다.


forEach 메서드가 동일한 반복을 처리하는 방법을 살펴 보겠습니다.


for 루프를 다음으로 바꿉니다.



const lists = ['item1', , 'item2', 'item3']
const newList = []

lists.forEach(function (list) {
  newList.push(list);
})

console.log(newList);


출력 :


["item1", "item2", "item3"]



무슨 일이야? 


forEach 메소드를 사용함으로써 우리는“목록 배열의 각 반복 요소 (즉, 개별 목록)에 대해 특정 기능을 수행합시다.


다시 말하지만, 함수는 모든 반복 요소를 newList 배열로 푸시합니다. 그러나 두 번째 배열 항목에 도달하면 forEach는 빈 슬롯을 건너 뛰고 계속 진행합니다.


코드를 더 최적화 해 보겠습니다.


ES6 화살표 함수를 사용하여 더 간결하게 만들 수 있습니다. 화살표 함수를 사용하여 콜백을 다시 작성하는 경우 다음이 있어야 합니다.



const lists = ['item1', , 'item2', 'item3']
const newList = []

lists.forEach((list) => newList.push(list))
console.log(newList);


콘솔을 저장하고 다시 방문하십시오. 완벽하게 작동합니다.


좋은. 그것은 좋은 시작입니다.


다른 선택적 콜백 매개 변수를 적용하여 한 단계 더 나아가 보겠습니다.


.js 파일에 다음 코드를 추가하기 만하면 됩니다.



let numbers = [2, 4, 6, 8, 10];

numbers.forEach((number, index, arr) => {
  arr[index] = number * 2; // arr = [2, 4, 6, 8, 10]
})

console.log(numbers);


평소와 같이 forEach는 숫자 배열을 반복하고 각 요소에 대해 콜백 함수를 실행합니다. 이 콜백에서 우리가 하는 일은 현재 반복되는 요소에 2를 곱하여 숫자 배열을 업데이트하는 것입니다.


그리고 우리는 arr [index]를 사용하여 배열과 인덱스를 참조합니다.


파일을 저장하십시오.


출력 :


[4, 8, 12, 16, 20]



forEach 메소드의 두 번째 인수 (즉 thisValue) 적용 


때로는 forEach 루프에서 이 키워드로 작업 할 수 있습니다. 키워드에 익숙하다면 다른 객체를 참조 할 수 있다는 것을 알게 될 것입니다.


해당 키워드를 관심 객체에 바인딩 하기 위해 JavaScript forEach는 구문에 지정된 대로 thisValue 인수를 제공합니다.


사용 사례를 살펴 보겠습니다.


.js 파일에 다음 코드를 추가하여 시작하십시오.




function MyNumber() {
  this.data = [];
}

MyNumber.prototype.multiply = function () {
  console.log("test");
}

const num = new MyNumber()

num.multiply();


객체 지향 스타일의 코드를 작성한 적이 있다면 위 내용에 익숙해야 합니다.


데이터 속성과 곱하기 메서드를 포함하는 생성자 함수 MyNumber를 정의했습니다.


코드에 익숙하지 않은 경우 자세한 내용을 설명하는 단계별 가이드가 있습니다. 


현재 코드는 별다른 일을 하지 않습니다. 저장하고 본체를 확인하면 "테스트"메시지 만 표시됩니다.


이제 다음과 같이 코드를 업데이트하겠습니다.



function MyNumber() {
  this.data = [];
}

MyNumber.prototype.multiply = function (numbers) {
  numbers.forEach(function (number) {
    console.log(this);
    this.data.push(number * 2)
  })
}

const num = new MyNumber()

num.multiply([2, 4, 6]);
console.log(num.data);



초점 영역은 곱하기 방법입니다. 그 함수는 forEach 메소드를 사용하여 루프하는 인수로 배열을 수신합니다.


여기서 논리는 새로운 배열 요소를 밀어 넣어 빈 데이터 배열을 업데이트하려는 것입니다. 따라서 콜백 내에서 이 키워드를 사용하여 데이터 속성을 참조해야 합니다.


하지만 파일을 저장하고 콘솔을 보면 다음과 같은 내용이 표시됩니다.


foreach thisValue 


콘솔 오류 외에도 forEach 내부에서 console.log (this)를 수행하기 때문에 Window 개체도 표시됩니다.


이것은 Window 인 전역 개체를 참조하고 있음을 의미합니다. 대신 현재 객체 인스턴스를 참조하기를 원합니다.


이것이 forEach의 두 번째 인수가 들어오는 곳입니다. 따라서 이것을 인수로 추가하고 파일을 저장하십시오. 당신은 잘해야 합니다.



numbers.forEach(function (number) {
  console.log(this);
  this.data.push(number * 2)
}, this)


콘솔을 다시 확인하면 이것이 이제 개체 인스턴스를 가리키고 있음을 알 수 있습니다.


산출:


[4, 8, 12]



화살표 함수를 콜백으로 사용 


콜백 함수를 화살표 함수로 바꾸면 forEach 메서드의 두 번째 매개 변수로 사용하지 않아도 됩니다. 이렇게 :




numbers.forEach((number) => {
  console.log(this);
  this.data.push(number * 2)
})


코드를 저장하고 테스트하십시오. 화살표 함수가 이 값을 어휘 적으로 바인딩 하기 때문에 작동합니다. 즉,이 키워드의 값은 컨텍스트 또는 주변 범위에 의해 결정됩니다.


ForEach() always return undefined 


잊기 쉽기 때문에 조심해야 합니다. forEach 함수를 반환하려고 하면 undefined 값이 표시됩니다.


.js 파일에 다음 코드를 추가합니다.



let numbers = [2, 4, 6, 8, 10];

const myNum = numbers.forEach(number => {
  return number * 2
})

console.log(myNum);


보시다시피 forEach 논리를 반환하고 결과를 myNum 변수에 할당합니다.


파일을 저장하고 콘솔을 열면 undefined 값이 표시됩니다.


무언가를 반환하고 싶다면 map()과 같은 다른 메소드를 사용하십시오. forEach와 비슷한 정의가 있습니다.


동일한 코드를 사용하여 forEach를 다음과 같은 map 메소드로 대체 해 보겠습니다.



let numbers = [2, 4, 6, 8, 10];

const myNum = numbers.map(number => {
  return number * 2
})

console.log(myNum);


파일을 저장하고 콘솔을 다시 방문하십시오.


산출:


[4, 8, 12, 16, 20]



forEach()와 달리 map() 메서드는 모든 배열 요소에 대해 함수를 호출 한 결과를 포함하는 새 배열을 반환합니다.


배열과 유사한 객체 작업 


HTML DOM으로 작업 한 적이 있다면 getElementsByClassName(), getElementsByTagName() 및 querySelectorAll()과 같은 DOM 메소드에 익숙해야 합니다.


이러한 메서드는 문서에서 여러 요소를 수집하는 데 사용할 수 있습니다. 그리고 그들은 HTMLCollection 또는 NodeList (둘 다 배열과 같은 객체)를 반환합니다.


이 섹션에서는 forEach를 사용하여 이러한 객체를 반복하는 방법을 배웁니다.


실용적인 예를 살펴 보겠습니다. .html 파일에 다음을 추가하십시오.



<ul class="list">
  <li class="list-item">item1</li>
  <li class="list-item">item2</li>
  <li class="list-item">item3</li>
  <li class="list-item">item4</li>
</ul>


DOM 메서드를 사용하여 모든 li 요소를 가져 오려고 하면 다음이 제공됩니다.



let itemsByClassName = document.getElementsByClassName('list-item')
console.log(itemsByClassName);

산출:



HTMLCollection(4) [li.list-item, li.list-item, li.list-item, li.list-item]
0: li.list-item
1: li.list-item
2: li.list-item
3: li.list-item
length: 4
__proto__ : HTMLCollection


또는



let itemsByQuerySelector = document.querySelectorAll('.list-item')
console.log(itemsByQuerySelector);


산출:



NodeList(4) [li.list-item, li.list-item, li.list-item, li.list-item]
0: li.list-item
1: li.list-item
2: li.list-item
3: li.list-item
length: 4
__proto__ : NodeList


출력에서 배열이라고 생각할 수 있습니다 (인덱스와 길이 속성이 포함되어 있기 때문에). 하지만 그렇지 않습니다!


HTMLCollection과 NodeList는 모두 배열처럼 보이는 객체이므로 Array와 같은 객체입니다.


즉, 대부분의 Array 메서드는 Array.prototype을 통해 사용할 수 있습니다. 사용할 수 없습니다. 대신 Object.prototype에서 메서드를 상속합니다.


그렇다면 어떻게 forEach를 사용하여 li 요소를 반복 할 수 있습니까?


다행히 NodeList는 forEach가 그중 하나 인 이러한 Array 메서드 중 몇 가지를 상속합니다. 따라서 다음과 같이 forEach 메서드를 사용하여 NodeList를 직접 반복 할 수 있습니다.



let itemsByQuerySelector = document.querySelectorAll('.list-item')

itemsByQuerySelector.forEach(item => console.log(item.innerText))


콜백에서 우리는 반복 된 각 요소에 대한 내부 텍스트를 로깅합니다.


산출:


item1
item2
item3
item4


HTMLCollection에 대해 동일한 작업을 수행하면 다음 오류가 발생합니다.


Uncaught TypeError: itemsByClassName.forEach is not a function



이러한 유형의 Array와 유사한 객체를 반복하려면 call() 메서드를 사용할 수 있습니다. 이를 통해 다른 객체에 속하는 메서드를 사용할 수 있습니다.


이 경우 Array.prototype 객체에서 사용할 수있는 forEach 메서드를 호출 한 다음 HTMLCollection에서 사용하려고 합니다.


코드는 다음과 같아야 합니다.



let itemsByClassName = document.getElementsByClassName('list-item')

Array.prototype.forEach.call(itemsByClassName, (item) => console.log(item.innerText))


콘솔을 저장하고 확인하십시오. 동일한 출력이 있어야 합니다.


배열과 유사한 객체를 배열로 변환 


배열과 유사한 객체를 반복하는 대신 먼저 배열로 변환하는 방법이 있습니다. Array.from()이라는 메서드를 사용하거나 이를 위해 Spread 구문 (…)을 사용할 수 있습니다.


빨리 살펴 보겠습니다.



let itemsByClassName = document.getElementsByClassName('list-item')
let itemsArray = Array.from(itemsByClassName)
console.log(itemsArray);


매우 간단합니다.


산출:


(4) [li.list-item, li.list-item, li.list-item, li.list-item]
0: li.list-item
1: li.list-item
2: li.list-item
3: li.list-item
length: 4
__proto__ : Array(0)



다음과 같이 스프레드 연산자를 사용하면 결과는 동일합니다.




let itemsByClassName = document.getElementsByClassName('list-item')
let itemsArray = [...itemsByClassName]
console.log(itemsArray);


확산 구문 (…)은 대괄호 안에 배열과 같은 객체를 "확장"하거나 확장하여 [] 적절한 배열을 만듭니다.


이제 배열에서 직접 forEach 메서드를 사용할 수 있습니다.


배열과 같은 객체의 또 다른 예입니다. 


정리하기 전에 다음과 같은 Array와 같은 객체의 구조를 볼 수 있습니다.



const arrayLike = {
  0: 'item1',
  1: 'item2',
  2: 'item3',
  length: 3
};


이전의 한 번과 달리 이 유형은 반복 할 수 없으며 스프레드 구문을 사용하여 배열로 변환 할 수 없습니다. 이 경우 다음과 같이 Array.from ()을 사용하면 됩니다.


const newArray = Array.from(arrayLike)
console.log(newArray);


산출:


["item1", "item2", "item3"]



여기에서 출력에 대해 forEach 메서드를 호출하여 반복 할 수 있습니다.


또는 원하는 경우 다음과 같이 call() 메서드를 사용하여 간접적으로 forEach를 호출하는 이전 메서드를 사용하면 됩니다.


const arrayLike = {
  0: 'item1',
  1: 'item2',
  2: 'item3',
  length: 3
};

Array.prototype.forEach.call(arrayLike, (item) => console.log(item))


파일을 저장하고 콘솔을 확인하면 항목이 표시됩니다.


결론 


forEach 메서드의 거의 모든 사용 사례를 살펴 보았습니다. 간단한 배열을 반복하는 것부터 배열과 유사한 객체를 다루는 작업과 그 사이에 있는 거의 모든 작업에 이르기까지. 이제 프로젝트에 적용 할 수 있습니다.


https://dev.to/ibaslogic/javascript-foreach-a-comprehensive-guide-for-beginners-5cao