본문 바로가기

Front End/Javascript

[JavaScript] Spread Operator(전개 연산자) 기본 사용법

Spread의 영단어 뜻을 검색해보면 펼치다라는 뜻이 나옵니다.

자바스크립트에서도 뜻 그대로 어떠한 문자열, 배열, 객체등을 감싸고 있는것을 전개 연산자( ...) 문법을 통하여 감싸고 있는 것을 펼쳐주는거라고 보시면 됩니다.

 

간단한 예를 보겠습니다.

spread_ex01.html 파일을 다음과 같이 만듭니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        let array = "한놈,두시기,석삼,너구리,오징어,육계장,칠면조,팔다리,구두쇠,쨍그랑".split(",");
        let hello = "Hello World";
        console.log(array);
        console.log(...array); // 한놈 두시기 석삼 너구리 오징어 육계장 칠면조 팔다리 구두쇠 쨍그랑
        console.log(hello);
        console.log(...hello); // H e l l o   W o r l d
    </script>
</head>
<body>
</body>
</html>
cs

 

실행 결과 입니다.

 

배열은 []를 없애고 공백으로 구분하여 "한놈 두시기 석삼 너구리 오징어 육계장 칠면조 팔다리 구두쇠 쨍그랑" 출력해주고 문자열은 한글자씩 분해해서 "H e l l o   W o r l d"로 출력해 줍니다. 뜻 그대로 펼쳐 준다고 볼 수 있습니다.

 

배열, 문자열 전개

spread_ex02.html 파일을 다음과 같이 만듭니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        let array = "한놈,두시기,석삼,너구리,오징어,육계장,칠면조,팔다리,구두쇠,쨍그랑".split(",");
        let [one, two, three, ...remain] = array;
        console.log(`${one} = ${two} = ${three} ==> ${remain}`);
        document.write(`one = ${one}<br>`);
        document.write(`two = ${two}<br>`);
        document.write(`three = ${three}<br>`);
        remain.forEach((data, index)=>{
            document.write(`remain[${index}] = ${data}<br>`);
        });
 
        let hello = "Hello World";
        let [...chars] = [...hello];
        console.log(`${typeof(chars)} : ${chars}`);
        document.write(chars.join("=>"+ "<br>");
    </script>
</head>
<body>
</body>
</html>
cs

 

실행 결과 화면입니다.

 

비구조화 할당(destructuring assignment) 구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 자바스크립트 표현식(expression)입니다. 간단하게 정리하면 배열 [], 혹은 객체 {} 안의 값을 편하게 꺼내 쓸 수 있는 문법입니다.

 

다음 명령은 배열의 요소들을 차례대로 좌변에 있는 변수에 복사하고 나머지는 remain이라는 배열로 만들어 줍니다.

let [one, two, three, ...remain] = array;

 

다음의 명령은 hello라는 문자열을 저장하고 있는 변수의 내용을 1글자씩 펼쳐서 chars라는 배열로 만들어 줍니다.

let [...chars] = [...hello];

 

좌항이 호출될 변수명들의 집합, 우항이 할당할 값 입니다.
좌항의 각 요소에는 같은 index를 가지는 배열값이 할당됩니다.
또한 전개 연산자(Spread Operator :  ... )를 사용하여 좌항에서 명시적으로 할당되지 않은 나머지 배열 값들을 사용할 수 있습니다.

 

그리고 var, let, const를 사용해 변수들의 유효 범위를 명시적으로 선언할 수 있습니다.
var [a, b, ...list] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let [a, b, ...list] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
const [a, b, ...list] = [1, 2, 3, 4, 5, 6, 7, 8, 9];

전개 연산자 이후에 변수를 입력하거나, 좌 우항이 다른 속성일 경우 에러가 발생합니다.
[a, b, ...list, c] = [1, 2, 3, 4, 5, 6, 7, 8, 9]; // error
[a, b, ...list] = {a : 10, b: 20}; // error

 

객체의 전개

spread_ex03.html 파일을 다음과 같이 만듭니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        let obj = { a: 10, b: 20, c: 30, d: 40 };
        document.write("obj : " + obj + " >> " + JSON.stringify(obj) + "<br>");
        
        let { a, b, ...remain_object } = obj;
        document.write(`a : ${a} <br>`);
        document.write(`b : ${b} <br>`);
        document.write(`remain_object : ${remain_object} >> ${JSON.stringify(remain_object)}<br>`);
        document.write("<hr>");
 
        var { a : first_name, b : second_name , ...remain_object2 } = { a : "한놈", b : "두식이", c : "석삼", d : "너구리" };
        document.write(`first_name : ${first_name} <br>`); 
        document.write(`second_name : ${second_name} <br>`); 
        document.write(`remain_object2 : ${remain_object2} >> ${JSON.stringify(remain_object2)} <br>`);
        document.write("<hr>");
 
        let key = 'second name'
        var {'first-name':first_name, [key]:second_name } = {'first-name' :  "한놈"'second name' : "두식이"};
        document.write(`first_name : ${first_name} <br>`); 
        document.write(`second_name : ${second_name} <br>`); 
        document.write("<hr>");
 
        ({a:first, b:second } = { a : 10, b : 20});
        document.write(`first : ${first} <br>`); 
        document.write(`second : ${second} <br>`); 
        document.write("<hr>");
        // { c, d } = { c : 30, d : 40}; // error
    </script>
</head>
<body>
</body>
</html>
cs

 

실행 결과 화면입니다.

객체의 경우에는 우항의 key 값이 좌항의 변수명과 매칭됩니다.
배열과 마찬가지로 var, let, const가 적용 가능합니다.

let obj = { a: 10, b: 20, c: 30, d: 40 };
let
 { a, b, ...remain_object } = obj;
document.write(`a : ${a} <br>`); // a : 10
document.write(`b : ${b} <br>`); // b : 20
document.write(`remain_object : ${remain_object} >> ${JSON.stringify(remain_object)}<br>`); //  {"c":30,"d":40}

 

원래의 key 값과 다른 이름의 변수를 사용하는 방법은 아래와 같습니다.

var { a : first_name, b : second_name , ...remain_object2 } = { a : "한놈", b : "두식이", c : "석삼", d : "너구리" };
document.write(`first_name : ${first_name} <br>`);  // first_name : 한놈
document.write(`second_name : ${second_name} <br>`); // second_name : 두식이
document.write(`remain_object2 : ${remain_object2} >> ${JSON.stringify(remain_object2)} <br>`); // {"c":"석삼","d":"너구리"}

 

또한 우항의 key값에 변수명으로 사용 불가능한 문자열이 있을경우 아래와 같은 방식으로 비구조화 할 수 있습니다.
'second name'은 공백이 있어서 안되고 'first-name'은 -를 연산자로 인식해서 안됩니다. 이때는 다음과 같이 합니다.

let key = 'second name'
var {'first-name':first_name, [key]:second_name } = {'first-name' :  "한놈"'second name' : "두식이"};
document.write(`first_name : ${first_name} <br>`);  // first_name : 한놈
document.write(`second_name : ${second_name} <br>`); // second_name : 두식이
 객체 비구조화에서 주의해야 할 점은 변수 선언에 대한 명시(var, let, const)가 없을 경우 괄호를 사용하여 묶어주어야 한다는 것 입니다.
({a:first, b:second } = { a : 10, b : 20});
document.write(`first : ${first} <br>`);  // first : 10
document.write(`second : ${second} <br>`); // second : 20
// { c, d } = { c : 30, d : 40}; // error

 

기본값 할당

 

spread_ex04.html 파일을 다음과 같이 만듭니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        [first, second] = [10];
        document.write(`first : ${first} <br>`); 
        document.write(`second : ${second} <br>`); 
        document.write("<hr>");
        
        var {first, second} = { first : 20};
        document.write(`first : ${first} <br>`); 
        document.write(`second : ${second} <br>`); 
        document.write("<hr>");
 
        [first=10, second=20= [10];
        document.write(`first : ${first} <br>`); 
        document.write(`second : ${second} <br>`); 
        document.write("<hr>");
 
        var {first=10, second=20= {};
        document.write(`first : ${first} <br>`); 
        document.write(`second : ${second} <br>`); 
        document.write("<hr>");        
    </script>
</head>
<body>
</body>
</html>
cs

 

실행 결과 화면입니다.

 

비구조화의 범위를 벗어나는 값 할당을 시도하면 undefined를 반환하게 됩니다.

[first, second] = [10]; // 좌변에 2개 우변에 1개
document.write(`first : ${first} <br>`);  // first : 10
document.write(`second : ${second} <br>`); // second : undefined

var {first, second} = { first : 20}; // 좌변에 2개 우변에 1개
document.write(`first : ${first} <br>`); // first : 10
document.write(`second : ${second} <br>`); // second : undefined

 

이런 경우를 방어하기 위해 호출될 변수명들에 기본값 할당을 할 수 있습니다.
다음과 같은 방법으로 변수명들에 할당 연산자(=)를 사용하여 기본값 할당을 할 수 있습니다.
객체에서 새로운 변수명에 할당하는 방식에도 기본값 할당을 사용할 수 있습니다.

[first=10, second=20= [10]; // 좌변에 기본값 할당
document.write(`first : ${first} <br>`); // first : 10
document.write(`second : ${second} <br>`); // second : 20
 
var {first=10, second=20= {}; // 좌변에 기본값 할당
document.write(`first : ${first} <br>`); // first : 10
document.write(`second : ${second} <br>`); // second : 20