Spread 구문을 사용하면 배열이나 문자열과 같이 반복 가능한 문자를 0개 이상의 인수 (함수로 호출할 경우) 또는 요소 (배열 리터럴의 경우)로 확장하여, 0개 이상의 키-값의 쌍으로 객체로 확장시킬 수 있다.

문법

함수 호출:

myFunction(...iterableObj);

배열 리터럴, 문자열:

[...iterableObj, '4', 'five', 6];

객체 리터럴 (new in ECMAScript 2018):

let objClone = { ...obj };

예제

함수 호출에서의 Spread

apply 대체

일반적으로 배열의 엘리먼트를 함수의 인수로 사용하고자 할 때 Function.prototype.apply 를 사용하였습니다.

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);

Spread 문법을 사용해 위 코드는 다음과 같이 작성될 수 있습니다.

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);

인수 목록의 모든 인수는 spread 문법을 사용할 수 있으며, 여러번 사용될 수도 있습니다.

function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);

new 에 적용

new 를 사용해 생성자를 호출 할 때, 배열과 apply (apply 는 [[Call]] 을 하지만 [[Construct]] 는 그렇지 않음) 를 직접 사용하는 것은 불가했습니다. 하지만, spread 문법 덕분에 배열을 new 와 함께 쉽게 사용될 수 있습니다.

var dateFields = [1970, 0, 1];  // 1 Jan 1970
var d = new Date(...dateFields);

Spread 문법 없이 파라미터의 배열과 함께 new 를 사용하려면, 부분적인 어플리케이션을 통해 간접적으로 해야 합니다.

function applyAndNew(constructor, args) {
   function partial () {
      return constructor.apply(this, args);
   };
   if (typeof constructor.prototype === "object") {
      partial.prototype = Object.create(constructor.prototype);
   }
   return partial;
}


function myConstructor () {
   console.log("arguments.length: " + arguments.length);
   console.log(arguments);
   this.prop1="val1";
   this.prop2="val2";
};

var myArguments = ["hi", "how", "are", "you", "mr", null];
var myConstructorWithArguments = applyAndNew(myConstructor, myArguments);

console.log(new myConstructorWithArguments);
// (internal log of myConstructor):           arguments.length: 6
// (internal log of myConstructor):           ["hi", "how", "are", "you", "mr", null]
// (log of "new myConstructorWithArguments"): {prop1: "val1", prop2: "val2"}

배열 리터럴에서의 Spread

더 강력한 배열 리터럴

Spread 문법 없이, 이미 존재하는 배열을 일부로 하는 새로운 배열을 생성하기에, 배열 리터럴 문법은 더 이상 충분하지 않으며 push, splice, concat 등의 조합을 사용하는 대신 명령형 코드를 사용해야 했습니다. Spread 문법으로 이는 훨씬 더 간결해졌습니다.

var parts = ['shoulders', 'knees']; 
var lyrics = ['head', ...parts, 'and', 'toes']; 
// ["head", "shoulders", "knees", "and", "toes"]

인수 목록을 위한 spread 처럼, ... 은 배열 리터럴의 어디에서든 사용될 수 있으며 여러번 사용될 수도 있습니다.

배열 복사

var arr = [1, 2, 3];
var arr2 = [...arr]; // arr.slice() 와 유사
arr2.push(4); 

// arr2 은 [1, 2, 3, 4] 이 됨
// arr 은 영향을 받지 않고 남아 있음

알림: Spread 문법은 배열을 복사할 때 1 레벨 깊이에서 효과적으로 동작합니다. 그러므로, 다음 예제와 같이 다차원 배열을 복사하는것에는 적합하지 않을 수 있습니다(Object.assign() 과 spread 문법이 동일합니다),

var a = [[1], [2], [3]];
var b = [...a];
b.shift().shift(); // 1
// 이제 배열 a 도 영향을 받음: [[], [2], [3]]

배열을 이어붙이는 더 나은 방법

Array.concat 은 배열을 존재하는 배열의 끝에 이어붙이는데 종종 사용됩니다. Spread 문법 없이, 이는 다음과 같이 작성됩니다.

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// arr2 의 모든 항목을 arr1 에 붙임
arr1 = arr1.concat(arr2);

Spread 문법을 사용해 이는 다음과 같아집니다.

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2];

Array.unshift 는 존재하는 배열의 시작 지점에 배열의 값들을 삽입하는데 종종 사용됩니다. Spread 문법 없이, 이는 다음과 같이 작성됩니다.

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
// arr2 의 모든 항목을 arr1 의 앞에 붙임
Array.prototype.unshift.apply(arr1, arr2) // arr1 은 이제 [3, 4, 5, 0, 1, 2] 가 됨

Spread 문법으로, 이는 다음과 같아집니다[하지만, 새로운 arr1 배열을 생성한다는 것에 유의합니다. 기존 arr1 배열을 수정하지 않습니다].

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr2, ...arr1]; // arr1 은 이제 [3, 4, 5, 0, 1, 2] 가 됨

객체 리터럴에서의 Spread

ECMAScript 의 Rest/Spread 프로퍼티 제안 (stage 4) 은 object literals 에 spread 프로퍼티를 추가합니다. 이는 제공된 객체가 소유한 열거형 프로퍼티를 새로운 객체로 복사합니다.

얕은 복제(prototype 제외) 또는 객체의 병합은 이제 Object.assign() 보다 더 짧은 문법을 사용해 가능합니다.

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

Object.assign()setters 를 트리거하지만 spread 구문은 그렇지 않음을 유의합니다.

 

Object.assign() 함수를 대체하거나 흉내낼 수 없음을 유의합니다.

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
const merge = ( ...objects ) => ( { ...objects } );

var mergedObj = merge ( obj1, obj2);
// Object { 0: { foo: 'bar', x: 42 }, 1: { foo: 'baz', y: 13 } }

var mergedObj = merge ( {}, obj1, obj2);
// Object { 0: {}, 1: { foo: 'bar', x: 42 }, 2: { foo: 'baz', y: 13 } }

위 예제에서, spread 문법은 예상대로 동작하지 않습니다. 나머지 매개변수로 인해, 인수 배열을 객체 리터럴로 spread 합니다.

 

이터러블 전용

Spread 문법 (spread 프로퍼티인 경우 제외) 은 iterable 객체에만 적용됩니다.

var obj = {'key1': 'value1'};
var array = [...obj]; // TypeError: obj is not iterable

많은 값과 Spread

함수 호출에서 spread 문법을 사용할 때, 자바스크립트 엔진의 인수 길이 제한을 초과하지 않도록 주의합니다. 자세한 내용은 apply() 를 보세요.

Rest 문법 (파라미터)

Rest 문법은 spread 문법과 완전 같아보이지만, 배열이나 객체를 해체하는데 사용됩니다. 어떤 면에서, rest 문법은 spread 문법과 반대입니다. Spread 는 배열을 그 엘리먼트로 '확장' 하는 반면, rest 는 여러 엘리먼트를 수집하며 이를 하나의 엘리먼트로 '압축' 합니다. Rest 파라미터 문서를 보세요.

명세

명세 상태 코멘트
ECMAScript 2015 (6th Edition, ECMA-262) Standard 명세의 여러 섹션에서 정의 됨: Array InitializerArgument Lists
ECMAScript 2018 (ECMA-262) Standard Object Initializer 에서 정의됨
ECMAScript Latest Draft (ECMA-262) Draft 변동 없음.
ECMAScript Latest Draft (ECMA-262) Draft 변동 없음.

브라우저 호환성

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidEdge MobileFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
Spread in array literalsChrome Full support 46Edge Full support 12Firefox Full support 16IE No support NoOpera Full support 37Safari Full support 8WebView Android Full support 46Chrome Android Full support 46Edge Mobile Full support 12Firefox Android Full support 16Opera Android Full support 37Safari iOS Full support 8Samsung Internet Android Full support 5.0nodejs Full support 5.0.0
Full support 5.0.0
Full support 4.0.0
Disabled
Disabled From version 4.0.0: this feature is behind the --harmony runtime flag.
Spread in function callsChrome Full support 46Edge Full support 12Firefox Full support 27IE No support NoOpera Full support 37Safari Full support 8WebView Android Full support 46Chrome Android Full support 46Edge Mobile Full support 12Firefox Android Full support 27Opera Android Full support 37Safari iOS Full support 8Samsung Internet Android Full support 5.0nodejs Full support 5.0.0
Full support 5.0.0
Full support 4.0.0
Disabled
Disabled From version 4.0.0: this feature is behind the --harmony runtime flag.
Spread in destructuringChrome Full support 49Edge No support NoFirefox Full support 34IE No support NoOpera Full support 37Safari ? WebView Android Full support 49Chrome Android Full support 49Edge Mobile No support NoFirefox Android Full support 34Opera Android Full support 37Safari iOS ? Samsung Internet Android Full support 5.0nodejs Full support Yes
Spread in object literals
Experimental
Chrome Full support 60Edge No support NoFirefox Full support 55IE No support NoOpera Full support 47Safari Full support 11.1WebView Android Full support 60Chrome Android Full support 60Edge Mobile No support NoFirefox Android Full support 55Opera Android ? Safari iOS Full support 11.1Samsung Internet Android Full support 8.2nodejs Full support 8.3.0
Full support 8.3.0
Full support 8.0.0
Disabled
Disabled From version 8.0.0: this feature is behind the --harmony runtime flag.

Legend

Full support  
Full support
No support  
No support
Compatibility unknown  
Compatibility unknown
Experimental. Expect behavior to change in the future.
Experimental. Expect behavior to change in the future.
User must explicitly enable this feature.
User must explicitly enable this feature.

함께 보기

문서 태그 및 공헌자

이 페이지의 공헌자: cs09g, cnaa97, ageofsys
최종 변경자: cs09g,