이 번역은 완료되지 않았습니다. 이 문서를 번역해 주세요.

forEach() 메서드는 주어진 함수를 배열 요소 각각에 대해 실행합니다.

구문

arr.forEach(callback[, thisArg]);

매개변수

callback
각 요소에 대해 실행할 함수. 다음 세 가지 인수를 받습니다.
currentValue
처리할 현재 요소.
index Optional
처리할 현재 요소의 인덱스.
array Optional
forEach()를 호출한 배열.
thisArg Optional
callback을 실행할 때 this로 사용할 값.

반환 값

undefined.

설명

forEach()는 주어진 callback을 배열에 있는 각 요소에 대해 오름차순으로 한 번씩 실행합니다. 삭제했거나 초기화하지 않은 인덱스 속성에 대해서는 실행하지 않습니다. (예: 희소 배열)

callback은 다음 세 인수와 함께 호출됩니다.

  • 요소 값
  • 요소 인덱스
  • 순회 중인 배열

thisArg 매개변수를 forEach()에 제공한 경우 callback을 호출할 때 전달해 this의 값으로 쓰입니다. 전달하지 않으면 undefined를 사용하며, 최종 this 값은 함수의 this를 결정하는 평소 규칙을 따릅니다.

forEach()로 처리할 요소의 범위는 최초 callback 호출 전에 설정됩니다. forEach() 호출을 시작한 뒤 배열에 추가한 요소는 callback이 방문하지 않습니다. 배열의 기존 요소값이 바뀐 경우, callback에 전달하는 값은 forEach()가 요소를 방문한 시점의 값을 사용합니다. 방문하기 전에 삭제한 요소는 방문하지 않습니다.

forEach()는 각 배열 요소에 대해 한 번씩 callback 함수를 실행합니다. map()과 reduce()와는 달리 undefined를 반환하기 때문에 메서드 체인의 중간에 사용할 수 없습니다. 대표적인 사용처는 메서드 체인 끝에서 부작용side effect을 실행하는 겁니다.

forEach()는 배열을 변형하지 않습니다. 그러나 callback이 변형할 수는 있습니다.

예외를 던지지 않고는 forEach()를 중간에 멈출 수 없습니다. 중간에 멈춰야 한다면 forEach()가 적절한 방법이 아닐지도 모릅니다.

다음 방법으로는 조기에 반복을 종료할 수 있습니다.

다른 배열 메서드, every()some()find(), findIndex()는 배열 요소를 판별 함수에 전달하고, 그 결과의 참/거짓 여부에 따라 반복의 종료 여부를 결정합니다.

예제

for 반복문을 forEach로 바꾸기

const items = ['item1', 'item2', 'item3'];
const copy = [];

// 이전
for (let i=0; i<items.length; i++) {
  copy.push(items[i]);
}

// 이후
items.forEach(function(item){
  copy.push(item);
});

배열 콘텐츠 출력

참고: console.table()을 사용하면 배열 내용물을 서식에 맞춰 출력할 수 있습니다. 다음 예제는 forEach()를 사용한 다른 방법을 소개합니다.

다음 코드는 배열의 각 요소에 대해 한 줄을 기록합니다:

function logArrayElements(element, index, array) {
  console.log('a[' + index + '] = ' + element);
}

// 인덱스 2는 배열의 그 위치에 항목이 없기에
// 건너뜀을 주의하세요.
[2, 5, , 9].forEach(logArrayElements);
// 기록:
// a[0] = 2
// a[1] = 5
// a[3] = 9

thisArg 사용

다음 (지어낸) 예는 배열의 각 항목에서 객체의 속성을 갱신합니다:

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

thisArg 매개변수(this)를 forEach()에 제공했기에, callback은 전달받은 this의 값을 자신의 this 값으로 사용할 수 있습니다. 

화살표 함수 식을 사용하여 함수 인수를 전달하는 경우 thisArg 매개변수는 화살표 함수가 this 값을 렉시컬(lexical, 정적) 바인딩하기에 생략될 수 있습니다.

객체 복사 함수

다음 코드는 주어진 객체의 사본을 만듭니다. 객체 사본을 만드는 여러 방법이 있습니다, 다음은 그저 한 방법으로 ECMAScript 5 Object.* 메타 속성 함수를 사용하여 Array.prototype.forEach()가 작동하는 법을 설명하기 위해 제시되었습니다.

function copy(obj) {
  var copy = Object.create(Object.getPrototypeOf(obj));
  var propNames = Object.getOwnPropertyNames(obj);

  propNames.forEach(function(name) {
    var desc = Object.getOwnPropertyDescriptor(obj, name);
    Object.defineProperty(copy, name, desc);
  });

  return copy;
}

var obj1 = { a: 1, b: 2 };
var obj2 = copy(obj1); // obj2는 이제 obj1처럼 보임

반복 중에 배열이 변경되면 다른 요소들을 건너 뛸 수도 있습니다.

다음 예제에서는 "one", "two", "four"를 기록합니다. 값 "two"를 포함하는 항목에 도달하면 전체 배열의 첫 번째 항목이 제거되어 나머지 항목이 한 위치 앞으로 이동합니다. 요소 "four"는 이제 배열의 앞쪽 위치에 있으므로 "three"는 건너 뜁니다. forEach()는 반복하기 전에 배열 복사본을 만들지 않습니다.

var words = ['one', 'two', 'three', 'four'];
words.forEach(function(word) {
  console.log(word);
  if (word === 'two') {
    words.shift();
  }
});
// one
// two
// four

폴리필

forEach는 ECMA-262 표준 제5판에 추가됐으므로 어떤 표준 구현체에서는 사용하지 못할 수도 있습니다. 다른 모든 코드 이전에 아래 코드를 포함하면 forEach를 지원하지 않는 환경에서도 사용할 수 있습니다. 아래 알고리즘은 ObjectTypeError가 변형되지 않고, callback.call()의 평가 값이 원래의 Function.prototype.call()과 같은 경우 ECMA-262 제5판이 명시한 것과 동일합니다.

// ECMA-262 5판, 15.4.4.18항의 작성 과정
// 참고: http://es5.github.io/#x15.4.4.18
if (!Array.prototype.forEach) {

  Array.prototype.forEach = function(callback, thisArg) {

    var T, k;

    if (this === null) {
      throw new TypeError(' this is null or not defined');
    }

    // 1. O를 인수로서 |this| 값을 전달한
    // toObject() 호출의 결과이게 함.
    var O = Object(this);

    // 2. lenValue를 "length" 인수가 있는 O의 Get()
    // 내부 메소드 호출의 결과이게 함.
    // 3. len을 toUint32(lenValue)이게 함.
    var len = O.length >>> 0;

    // 4. isCallable(callback)이 false인 경우, TypeError 예외 발생.
    // 참조: http://es5.github.com/#x9.11
    if (typeof callback !== "function") {
      throw new TypeError(callback + ' is not a function');
    }

    // 5. thisArg가 공급됐다면, T를 thisArg이게 함;
    // 아니면 T를 undefined이게 함.
    if (arguments.length > 1) {
      T = thisArg;
    }

    // 6. k를 0이게 함
    k = 0;

    // 7. 반복, k < len일 동안
    while (k < len) {

      var kValue;

      // a. Pk를 ToString(k)이게 함.
      //    이는 in 연산자의 좌변(LHS) 피연산자에 대한 묵시(implicit)임
      // b. kPresent를 Pk 인수가 있는 O의 HasProperty
      //    내부 메소드 호출의 결과이게 함.
      //    이 과정은 c와 결합될 수 있음
      // c. kPresent가 true인 경우, 그러면
      if (k in O) {

        // i. kValue를 인수 Pk가 있는 O의 Get 내부
        // 메소드 호출의 결과이게 함.
        kValue = O[k];

        // ii. this 값으로 T 그리고 kValue, k 및 O을 포함하는
        // 인수 목록과 함께 callback의 call 내부 메소드 호출.
        callback.call(T, kValue, k, O);
      }
      // d. k를 1씩 증가.
      k++;
    }
    // 8. undefined 반환
  };
}

명세

명세 상태 설명
ECMAScript 5.1 (ECMA-262)
The definition of 'Array.prototype.forEach' in that specification.
Standard 초기 정의. JavaScript 1.6에서 구현됨.
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Array.prototype.forEach' in that specification.
Standard  
ECMAScript Latest Draft (ECMA-262)
The definition of 'Array.prototype.forEach' in that specification.
Draft  

브라우저 호환성

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
forEachChrome Full support YesEdge Full support 12Firefox Full support 1.5IE Full support 9Opera Full support YesSafari Full support YesWebView Android Full support YesChrome Android Full support YesEdge Mobile Full support YesFirefox Android Full support 4Opera Android Full support YesSafari iOS Full support YesSamsung Internet Android Full support Yesnodejs Full support Yes

Legend

Full support  
Full support

같이 보기

문서 태그 및 공헌자

최종 변경자: mdnwebdocs-bot,