[JavaScript] spread operator(전개연산자)

배열에서의 전개연산자

// 기본동작원리코드
const fruits1 = ["apple", "orange", "banana"];
const fruits2 = [...fruits1];

console.log(fruits1); // [ 'apple', 'orange', 'banana' ]
console.log(fruits2); // [ 'apple', 'orange', 'banana' ]
console.log(fruits1 === fruits2); //false


(fruit1 === fruit2); //false 결과가 나온 이유는 immutable array와 같은 개념으로 참조가아닌 원본객체 복사하여 새로운 fruit 객체를 만든것이기 때문이다.

직접 확인해보면 아래와 같다.
const fruits1 = ["apple", "orange", "banana"];
const fruits2 = [...fruits1];

// console.log(fruits1); // [ 'apple', 'orange', 'banana' ]
// console.log(fruits2); // [ 'apple', 'orange', 'banana' ]
// console.log(fruits1 === fruits2); //false

fruits1.push("watermelon");
console.log(fruits1); // [ 'apple', 'orange', 'banana', 'watermelon' ]
console.log(fruits2); // [ 'apple', 'orange', 'banana' ]


fruit1에 값을 추가하여도 값만 복제되었을뿐 동일한 메모리를 참조하는것이 아니기때문에 다른 값이 나온다.


하지만 배열안에 객체를 사용하는경우는 다르게 동작하게된다.

const book1 = { title: "자바스크립트", cost: 10000 };
const book2 = { name: "리액트", page: 200 };

const bookCombine = [book1, book2];

const bookList = [...bookCombine];

book1.title = "앵귤러";

console.log(bookList); // [ { title: '앵귤러', cost: 10000 }, { name: '리액트', page: 200 } ]

배열과 달리 객체는 메모리 주소의 참조값을 복사해오는것이기 때문에 원본객체의 값을 수정하게되면 이를 참조하고있는 모든 메모리 주소에서의 값들이 변경이 발생하게 된다.



전재 연산자로 배열 병합 concat 을 대신하는 방법

//배열 병합시키기
const smallLetter = ["a", "b", "c", "d"];
const capitalLetter = ["A", "B", "C", "D"];

const combine = [...smallLetter, ...capitalLetter];

console.log(combine); // ["a", "b", "c", "d", "A", "B", "C", "D"]

전개연산자를 사용하면 배열에 다른배열을 추가하여 배열을 합치기도 가능하다.

추가적으로 

const array1 = [1, 2, 3, 4, 5];

const newArray = [...array1, 6, 7, 8, 9, 10];

console.log(newArray); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

전개연산자를 사용하면 값을 복제하고 배열에 값을 쉽게 추가할 수도 있다.


함수의 매개변수에 인자값을 전개연산자로 전달하기

const sum = (a, b, c) => {
return a + b + c;
};

const param = [100, 200, 300];

console.log(sum(...param)); //600

전개연산자를 사용하면 배열을 parameter로 전달할 수 있다. 두 코드가 모양만 다를뿐 똑같이 동작한다. apply메서드에 배열을 넣어 값을 출력할 수 있지만 전개연산자로도 apply메서드 없이 매개변수로 바로 전달하여 값을 출력할 수 있다.



Object에도 전개 연산자를 사용할 수 있다.

const book1 = { title: "자바스크립트", cost: 10000 };
const book2 = { name: "리액트", page: 300 };

const book3 = { ...book1, ...book2 };

console.log(book3); //{ title: '자바스크립트', cost: 10000, name: '리액트', page: 300 }

두개의 객체를 하나의 객체로 합칠 수 있고


const book1 = { title: "자바스크립트", cost: 10000 };

const book3 = { ...book1, page: 400 };

console.log(book3); //{ title: '자바스크립트', cost: 10000, page: 400 }

배열처럼 객체의 프로퍼티를 추가할 수 있으며


const book1 = { title: "자바스크립트", cost: 10000 };
const book2 = { title: "리액트", page: 300 };

const book3 = { ...book1, ...book2 };

console.log(book3); //{ title: '리액트', cost: 10000, page: 300 }

두 Object를 병합할 때 프로퍼티 key값이 동일하면 뒤에 작성한 key값으로 기존의 값을 덮어 쓰게 된다.


const book1 = { title: "자바스크립트", cost: 10000 };

const book3 = { ...book1 };

console.log(book1 === book3); // false

book1.title = "앵귤러";

console.log(book3); //{ title: '자바스크립트', cost: 10000 }

전개연산자를 사용하여 객체를 복제할때 메모리 주소를 참조하지않는 새로운 객체를 만들 수 있다.



여기서 헷갈릴만한 부분을 정리하면

맨위쪽에 예제에서 배열안에 객체를 담고나서 원본 객체의 값을 변경하면 배열안에 담은 객체들의 값이 변경된다.

그 이유는 배열안에 담은 객체들의 경우 값을 복제한것이 아닌 객체의 메모리 주소의 참조값을 복제한것이기 때문에 원본 객체의 값을 변경하면 해당 객체의 메모리 주소를 참조하고있는 모든 곳에서 값이 변경된다.

하지만 아래의 예제는 배열이 아닌 객체안에 객체 즉, 전개연산자를 사용하여 객체안에 객체를 복제하는 경우이기 때문에 메모리 주소를 참조하지않고 객체의 프로퍼티를 그대로 복사할 수 있다.

그래서 원본객체의 값을 변경하더라도 복제된곳에서 값의 변경이 발생되지 않는다.


댓글