이번 포스팅은 자바스크립트의 Spread 연산자에 대한 것 입니다. vue에서 자바스크립트를 사용하면서 Spread 연산자를 사용할 일이 있었고, 내용을 정리할 겸 포스팅하려고 합니다.
아래 식 처럼 복사를 하게 되면, arr의 값이 copyArr에 복사된 것이긴 하지만, 같은 주소값을 공유하게 됩니다.
따라서, copyArr의 값에 변화가 일어나면, arr도 동일하게 변화가 일어납니다. (이것은 자바에서도 마찬가지)
const arr = [1,2,3,4,5];
const copyArr = arr;
arr[1] = 8;
console.log(copyArr);
//[1, 8, 3, 4, 5]
Spread 연산자를 이용한다면, 배열이나 객체의 요소들만을 다른 배열에 복사가 가능합니다.
Spread 연산자는 배열에 있는 값들을 전개해주는 연산자
입니다. []나 {}가 벗겨진다고 생각하면 됩니다.
...
을 붙입니다.const arr = [1,2,3,4,5];
console.log(...arr);
//1,2,3,4,5 <- []가 벗겨짐.
Spread 연산자를 이용해서 []를 벗긴 뒤, 이것을 다시 []로 감싼다면, 동일한 값으로 복사가능하게 됩니다.
이렇게 되면, 값은 같지만, 주소값이 다른 배열로 복사가 가능하게 됩니다. 즉, arr의 값을 변경해도 copyArr에는 전혀 영향이 가지 않게 됩니다.
const arr = [1,2,3,4,5];
const copyArr = [...arr];
arr[1] = 9;
console.log(arr);
//[1, 9, 3, 4, 5]
console.log(copyArr);
//[1, 2, 3, 4, 5]
위의 코드처럼 복사를 하는 것을 얕은 복사(shallow copy)
라고 합니다.
객체를 이용해서 예를 다시 한번 들어보겠습니다.
const person = {
name : "kim",
age : 10,
}
const copyPerson = {...person}
console.log(copyPerson);
//{name: 'kim', age: 10}
그렇다면, 아래의 경우는 어떻게 될까요?
const person = {
name : "kim",
age : 10,
number : {num1:1, num2:2}
}
const copyPerson = {...person}
console.log(copyPerson);
/*{
name : "kim",
age : 10,
number : {num1:1, num2:2}
}*/
얕은 복사를 한 후 copyPerson의 요소를 바꿔보겠습니다.
copyPerson.name = "choi";
copyPerson.age = 20;
copyPerson.number.num1 = 5;
console.log(copyPerson);
/*{
name : "choi",
age : 20,
number : {num1:5, num2:2}
}*/
그렇다면, person의 데이터는 그대로일까요?
number의 num1이 바뀌었습니다.
console.log(person);
/*{
name : "kim",
age : 10,
number : {num1:5, num2:2}
}*/
이렇게 되는 이유는,
person과 copyPerson의 주소값은 다르지만, 이 두 객체에 들어있는 number라는 객체의 주소값은 동일하게 복사됩니다. 즉, number 객체의 주소값(Heap에 저장)은 공유하게 되는 것 입니다.
다시 말해서, 얕은 복사를 하더라도, 그 객체 안에 요소로 있는 배열이나 객체의 주소값은 바뀌지 않기 때문에 person이나 copyPerson의 객체 값에 변화가 일어난다면, 두 객체 모두 적용되게 됩니다.
만약 객체 안에 배열이나 객체가 들어있고, 이 객체를 복사하려 할 때, 원본과 복사본 서로에게 영향을 주지 않으려면 깊은 복사
를 해야합니다.
JSON.stringify()
와 JSON.parse()
가 필요합니다.JSON.stringify()
를 이용해서 객체를 모두 문자화 한 뒤,JSON.parse()
로 다시 객체로 바꾼 뒤 할당해 주면 됩니다.const person = {
name : "kim",
age : 10,
number : {num1:1, num2:2}
}
const copy = JSON.stringify(person); //객체를 Json형태의 문자로 변환
//'{"name":"kim","age":10,"number":{"num1":1,"num2":2}}'
const copyPerson = JSON.parse(copy);
/*{
name : "kim",
age : 10,
number : {num1:1, num2:2}
}*/
이제 person이나 copyPerson안에 있는 number 객체의 값에 변화를 줘도, 독립적으로 변화가 된다.
Reference