일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- socket.io
- 채팅방
- 후기
- setstate
- 동기
- useEffect
- 미리보기
- 항해99
- 개발
- 비동기
- 스파르타코딩클럽
- 7기
- react
- 브라우저 렌더링
- route
- S3
- 배포
- Github Actions
- routing
- 라우팅
- CI/CD
- Redux
- updater
- FileReader
- qwe
- previousState
- imagePreview
- 접근 제한 라우팅
- rendering
- Preview
- Today
- Total
삐옹
Javascript 객체 복사하기(1) 본문
Object는 알다가도 모를 놈이다.
복사한다고 했는데, 원본 바뀐다고 얘도 똑같이 바뀌면 어쩌자는거지.
에 대한 해결법이다.
상황
user1에 있는 데이터를 user2에 복사한 뒤
user1에 수정이 일어났을 때 무슨 일이 일어날까.
(user1의 데이터 타입이 *원시형일때와 **객체형 일 때 두가지 상황으로 나눠 설명합니다.)
*원시형(primitive type)
- String
- Boolean
- null
- undefined
- symbol (ES6에서 추가됨)
**객체형(object/reference type)
- object
원시 타입 데이터 복사
user1에 "mike"를 넣고, user2에 user1을 복사 해줍니다.
let user1 = "mike";
let user2 = user;
console.log(user1) // mike
그런데 실수를 했네요
user1에는 "mike가 아니라" "bob"을 넣었어야했습니다.
user1을 변경해주겠습니다.
let user1 = "mike";
let user2 = user;
user1 = "bob"; // "mike" -> "bob" 으로 변경합니다
console.log(user1); // bob
console.log(user2); // mike
user1을 콘솔을 찍어보니 "bob"으로 변경이 잘 이루어진걸 확인할 수 있습니다.
user2에는 실수로 기입했던 "mike"값이 그대로 들어있습니다.
이렇게 원시형 데이터를 복사했을 때는
자연스럽게 원본과 사본 데이터가 독립적입니다.
(이것을 객체복사에서는 다른 reference를 보고 있다고 말합니다.)
객체 타입 데이터 복사
유저의 정보를 조금 더 세분화 시켜보겠습니다.
let user1 = {name : "bob", age : 31};
let user2 = user1;
console.log(user1); // {name: 'bob', age: 31}
console.log(user2); // {name: 'bob', age: 31}
신경써야할 정보가 조금 더 늘었지만
역시나 user2에도 복사가 잘 이루어졌습니다.
이번에는 bob씨의 나이가 잘 못 기입되었다고 하네요.
수정해보겠습니다.
user1.age = 19;
console.log(user1); // {name: 'bob', age: 19}
console.log(user2); // {name: 'bob', age: 19}
변경이 잘 이루어졌습니다.
그런데 복사본 user2의 나이도 바뀌어버렸습니다.
user2가 변경되지 않게하려면 총 3가지 방법이 있습니다.
1. 빈 객체 생성해서 for문으로 값 넣어주기 (old)
2. Object.assign (new)
3. Spread 연산자 (new)
빈 객체 생성해서 for문으로 값 넣어주기
let user1 = {name : "bob", age : 31};
let user2 = {};
for(key in user1){
user2[key] = user1[key];
}
user1.name = "steven"
console.log(user1) // {name: 'steven', age: 31}
console.log(user2) // {name: 'bob', age: 31}
Object.assign() 함수
let user1 = {name : "bob", age : 31};
let user2 = {};
Object.assign(user2, user1); // Object.assign(새로 만들 변수, 복사할 변수)
user1.name = "steven"
console.log(user1) // {name: 'steven', age: 31}
console.log(user2) // {name: 'bob', age: 31}
역시 같습니다.
let user1 = {name : "bob", age : 31};
let user2 = Object.assign({}, user1);
user1.name = "steven"
console.log(user1) // {name: 'steven', age: 31}
console.log(user2) // {name: 'bob', age: 31}
3. Spread 연산자
let user1 = {name : "bob", age : 31};
let user2 = {...user1};
user1.name = "shallon";
console.log(user1); // {name: 'shallon', age: 31}
console.log(user2); // {name: 'bob', age: 31}
배열을 복사할 때도 똑같이 쓰면됩니다.
let user2 = ["mike", "chloe", "bob"]
let user1 = [...user2];
user1[0] = "venny";
console.log(user1) // ["venny", "chloe", "bob"]
console.log(user2) // ["mike", "chloe", "bob"]
세줄 요약
- 원시형과 객체형 데이터의 복사방법은 다르다.
- 원본데이터를 직접 건드려야 할 때는 이게 맞나 생각해보자.
- Object.assign()과 스프레드 연산자를 쓰자
참고
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
'Javascript' 카테고리의 다른 글
[자바스크립트 기초 #1] 자바스크립트 엔진(엔진 이해, 스택 개념) (0) | 2022.06.26 |
---|---|
map()과 forEach()의 차이점 (0) | 2022.05.22 |
가짜 배열 Nodelist (0) | 2022.05.21 |
반복문을 종료해보자. break? return? (0) | 2022.05.20 |
배열의 요소 삭제하는 5가지 방법 (0) | 2022.05.20 |