MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

현재 번역은 완벽하지 않습니다. 한국어로 문서 번역에 동참해주세요.

요약

map() 메소드는 배열 내의 모든 요소 각각에 대하여  제공된 함수(callback)를 호출하고, 그 결과를 모아서,  새로운 배열을 반환합니다.

문법

arr.map(callback[, thisArg])

파라미터

callback
새로운 배열 요소를 생성하는 함수로 다음 세 가지 인수를 가집니다.
currentValue
배열의 요소 중, 현재 처리되고 있는 요소
index
현재 처리되는 요소의 배열 내 인덱스
array
map 메소드가 적용되는 본래 배열
thisArg
선택항목. callback을 실행할 때 this로 사용되는 값. 기본값은 Window 객체.

설명

mapcallback함수를 각각의 요소에 대해 한번씩 순서대로 불러 그 함수의 리턴값(결과값)으로 새로운 배열을 만듭니다. callback함수는 (undefined도 포함해서) 배열 값이 들어있는 인덱스에 대해서만 호출됩니다. 즉, 값이 삭제되거나 아직 값이 할당/정의되지 않은 인덱스에 대해서는 호출되지 않습니다.

callback함수가 호출 될 때에는, 호출되는 대상 요소의 값, 그 요소의 인덱스 그리고, map 메소드가 사용된 배열 객체의 3개의 인수를 전달받습니다.

thisArg 매개변수가 map에 전달될 때에는, callback함수의 this값으로 사용됩니다.  thisArg 매개변수가 없을 때에는 undefined 값이 전달되고, 이때경우에는 callback 함수의 this 값은  the usual rules for determining the this seen by a function에 따라 최종적으로 결정됩니다.

map 은 호출된 배열의 값을 변형하지 않습니다 (단, callback 함수 호출에 의해서 변형될 수는 있습니다).

map이 처리를 수행하는 대상 요소들의 범위는 최초로 callback함수가 호출되기 전에 정해집니다. map이 호출된 이후에 배열에 추가된 요소들은 callback로 호출되지 않습니다. map이 처리를 수행할 대상으로 정해진 기존 요소들의 값이 바뀌거나 삭제되는 경우에는, map에 의해 해당 요소에 대해  callback 호출하던 시점에서의 값이 전달됩니다.;  삭제된 요소들에 대해서는 map이 처리를 수행하지 않습니다(callback 함수가 호출되지 않습니다).

예제

예제: 배열에 들어있는 숫자들의 제곱근을 구하여 새로운 배열을 만들기

다음 코드는 숫자의 배열을 받아 각 숫자들의 제곱근이 들어있는 새로운 배열을 만듭니다.

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots의 값은 [1, 2, 3]이 되지만, numbers는 그대로 [1, 4, 9]입니다.

예제: map을 활용해 오브젝트를 다시 재구성하기

다음 코드는 오브젝트들의 배열을 받아 각각의 오브젝트를 다른 형태으로 재구성해 새로운 배열을 만듭니다.

var kvArray = [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}];
var reformattedArray = kvArray.map(function(obj){ 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});
// reformattedArray는 [{1:10}, {2:20}, {3:30}]가 되지만, 
// kvArray는 여전히 [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]입니다.

예제: 숫자가 들어있는 배열을 인수가 있는 함수를 사용하여 재구성하기

The following code shows how map works when a function requiring one argument is used with it. The argument will automatically be assigned to each element of the array as map loops through the original array.

var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
  return num * 2;
});
// doubles is now [2, 8, 18]. numbers is still [1, 4, 9]

예제: map을 포괄적으로 사용하기

이 예제에서는 String 에  map을 사용해서 String내의 각 Byte의 ASCII코드값을 요소로 가지는 배열을 얻는 방법을 보여준다.:

var map = Array.prototype.map;
var a = map.call('Hello World', function(x) { return x.charCodeAt(0); });
// a now equals [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

예제: Using map generically querySelectorAll

이 예제는 querySelectorAll을 사용해서 수집된 객체들을 어떻게 반복 처리 하는지 보여줍니다. 이 경우, 스크린에 선택된 옵션(option)들을 콘솔에 프린트합니다.

var elems = document.querySelectorAll('select option:checked');
var values = [].map.call(elems, function(obj) {
  return obj.value;
});

예제: map으로 문자열 반전하기(Using map to reverse a string)

var str = '12345';
[].map.call(str, function(x) {
  return x;
}).reverse().join(''); 

// Output: '54321'
// Bonus: use '===' to test if original string was a palindrome

Tricky use case

(inspired by this blog post)

It is common to use the callback with one argument (the element being traversed). Certain functions are also commonly used with one argument, even though they take additional optional arguments. These habits may lead to confusing behaviors.

// Consider:
['1', '2', '3'].map(parseInt);
// While one could expect [1, 2, 3]
// The actual result is [1, NaN, NaN]

// parseInt is often used with one argument, but takes two.
// The first is an expression and the second is the radix.
// To the callback function, Array.prototype.map passes 3 arguments: 
// the element, the index, the array
// The third argument is ignored by parseInt, but not the second one,
// hence the possible confusion. See the blog post for more details

function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]
// Actual result is an array of numbers (as expected)

// A simpler way to achieve the above, while avoiding the "gotcha":
['1', '2', '3'].map(Number); // [1, 2, 3]

폴리필Polyfill

map was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of map in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming Object, TypeError, and Array have their original values and that callback.call evaluates to the original value of Function.prototype.call.

// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: http://es5.github.io/#x15.4.4.19
if (!Array.prototype.map) {

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

    var T, A, k;

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

    // 1. Let O be the result of calling ToObject passing the |this| 
    //    value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal 
    //    method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if (arguments.length > 1) {
      T = thisArg;
    }

    // 6. Let A be a new array created as if by the expression new Array(len) 
    //    where Array is the standard built-in constructor with that name and 
    //    len is the value of len.
    A = new Array(len);

    // 7. Let k be 0
    k = 0;

    // 8. Repeat, while k < len
    while (k < len) {

      var kValue, mappedValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal 
      //    method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if (k in O) {

        // i. Let kValue be the result of calling the Get internal 
        //    method of O with argument Pk.
        kValue = O[k];

        // ii. Let mappedValue be the result of calling the Call internal 
        //     method of callback with T as the this value and argument 
        //     list containing kValue, k, and O.
        mappedValue = callback.call(T, kValue, k, O);

        // iii. Call the DefineOwnProperty internal method of A with arguments
        // Pk, Property Descriptor
        // { Value: mappedValue,
        //   Writable: true,
        //   Enumerable: true,
        //   Configurable: true },
        // and false.

        // In browsers that support Object.defineProperty, use the following:
        // Object.defineProperty(A, k, {
        //   value: mappedValue,
        //   writable: true,
        //   enumerable: true,
        //   configurable: true
        // });

        // For best browser support, use the following:
        A[k] = mappedValue;
      }
      // d. Increase k by 1.
      k++;
    }

    // 9. return A
    return A;
  };
}

명세

Specification Status Comment
ECMAScript 5.1 (ECMA-262)
The definition of 'Array.prototype.map' in that specification.
Standard Initial definition. Implemented in JavaScript 1.6.
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Array.prototype.map' in that specification.
Standard  

브라우저 호환

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari
Basic support (Yes) 1.5 (1.8) 9 (Yes) (Yes)
Feature Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Basic support (Yes) (Yes) 1.0 (1.8) (Yes) (Yes) (Yes)

 

참고

문서 태그 및 공헌자

태그: 
 이 페이지의 공헌자: reoim, Yunhong-Min, sominlee, Rokt33r, webix
 최종 변경: reoim,