번역 작업 진행중입니다.

forEach() 메소드는 배열 요소마다 한 번씩 주어진 함수를 실행합니다.

문법(Syntax)

arr.forEach(function callback(currentValue[, index[, array]]) { //your iterator }[, thisArg]);

매개변수

callback
각 요소에 대해 실행할 인수 세개를 취하는 함수:
currentValueOptional
배열에서 처리될 현재 요소의 값
indexOptional
배열에서 처리될 현재 요소의 인덱스.
arrayOptional
forEach()가 적용되는 배열.
thisArgOptional
callback을 실행할 때 this (예: 참조 객체)로서 사용하는 값.

반환 값

undefined.

설명

forEach()는 오름차순으로 배열에 있는 각 요소에 대해 한 번씩 제공한 callback을 실행합니다. 삭제 또는 비초기화된 인덱스 속성에 대해서는 호출되지 않습니다(즉 듬성듬성한 배열의).

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

  • 요소 값
  • 요소 인덱스
  • 순회(traverse)될 배열

thisArg 매개변수가 forEach()에 제공된 경우, 이는 호출될 때 callback에 전달됩니다, this 값으로 쓰기 위해. 그렇지 않으면, undefined 값이 this 값으로 쓰기 위해 전달됩니다. 결국 callback에 의해 관찰할 수 있는 this 값은 함수에 의해 보이는 this를 결정하는 평소 규칙에 따라 결정됩니다.

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

forEach()는 각 배열 요소에 대해 한 번씩 callback 함수를 실행합니다; map() 또는 reduce()와는 달리 항상 undefined 값을 반환하고 연결(chain)할 수 없습니다. 대표 사용처(use case)는 체인 끝에서 부작용(side effect)을 실행하는 겁니다.

forEach() does not mutate the array on which it is called (although callback, if invoked, may do so).

 

There is no way to stop or break a forEach() loop other than by throwing an exception. If you need such behavior, the forEach() method is the wrong tool.

Early termination may be accomplished with:

The other Array methods: every()some()find(), and findIndex() test the array elements with a predicate returning a truthy value to determine if further iteration is required.

 

예시

 

for loop를 forEach로 바꾸기

이전

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

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

이후

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

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

 

배열 콘텐츠 인쇄

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

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 값으로 쓰기 위해.

화살표 함수 식을 사용하여 함수 인수를 전달하는 경우 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처럼 보임

 

If the array is modified during iteration, other elements might be skipped.

The following example logs "one", "two", "four". When the entry containing the value "two" is reached, the first entry of the whole array is shifted off, which results in all remaining entries moving up one position. Because element "four" is now at an earlier position in the array, "three" will be skipped. forEach() does not make a copy of the array before iterating.

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

 

폴리필(Polyfill)

forEach()는 ECMA-262 표준 제5판에 추가되었습니다; 그러하기에 다른 표준 구현에 없을 수 있습니다. 스크립트 시작 부분에 다음 코드를 삽입하여 이를 우회할 수 있습니다, 원래 이를 지원하지 않는 구현에서 forEach()를 사용케 하는. 이 알고리즘은 바로 ECMA-262 제5판에서 서술한 겁니다, ObjectTypeError가 원래값을 갖고 callback.call()Function.prototype.call()의 원래값으로 평가하는 것으로 여기는.

// 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  

Browser compatibility

The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out https://github.com/mdn/browser-compat-data and send us a pull request.

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidiOS SafariSamsung InternetNode.js
Basic supportChrome Full support YesEdge Full support YesFirefox 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

같이 보기

문서 태그 및 공헌자

이 페이지의 공헌자: Parcovia, limkukhyun, KisukPark, Netaras
최종 변경자: Parcovia,