Javascript

객체복사

2023. 4. 6. 01:32
목차
  1. 객체복사
  2. 기본형(원시타입)
  3. 참조형(객체)
  4. 참조에 의한 비교
  5. 객체복사
  6. object.assign
  7. 예시
  8. 혼자 해보기
  9. 중첩 객체 복사
  10. 요약

객체복사

- 객체와 원시타입의 근본적인 차이중 하나는 객체는 참조에 의해 저장되고 복사된다.

- 원시값은 값드래도 저장,할당되고 복사된다.

기본형(원시타입)

  • 복제방식: 값이담긴 주소값을 바로 복제
  • 불변성의 여부: 불변성을 띔

참조형(객체)

  • 복제방식: 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제
  • 불변성의 여부: 불변성을 띄지 않음
let sayHello = "Hello!";
let copy = sayHello;

console.log(sayHello) //"Hello!"
console.log(copy) // "Hello!"

- 예시를 실행하면 두 개의 독립된 변수에 각각 문자열 "Hello!"가 저장됨

- 객체의 동작 방식은 객체가 저장되어 있는 메모리 주소인 객체에 대한 참조 값이 저장됨

let user = {
  name: "John"
};

- 객체는 메모리 내 어딘가에 저장되고, 변수 user엔 객체를 참조 할 수 있는 값이 저장된다. 따라서 객체가 할당된 변수를 복사할 땐 객체의 참조 값이 복사되고 객체는 복사되지 않는다.

let user = { name: "John" };

let admin = user; // 참조값을 복사함

console.log(user)   //{name: 'John'}
console.log(admin)  //{name: 'John'}

- 변수는 두 개이지만 각 변수엔 동일 객체에 대한 참조 값이 저장

let user = { name: 'John' };

let admin = user;

admin.name = 'hi'; // 'admin' 참조 값에 의해 변경됨
admin.age = 30 //변수 'admin' 에 age:30 값을 추가

console.log(user.name , user.age); // 'hi , 30'이 출력됨. 'user' 참조 값을 이용해 변경사항을 확인함
console.log(user) // {name: "hi" , age: 30}

- 객체를 서랍장에 비유하면 변수는 서랍장을 열 수 있는 열쇠이다. 서랍장은 하나, 서랍장을 열 수 있는 열쇠는 두개인데 그중 하나(admin)를 사용해 서랍장을 열어 정돈한후, 또 다른 열쇠 (user)로 서랍장을 열면 정돈된 내용을 볼 수 있다.

서랍장은 하나다 = 저장된 값은 하나 

열수있는 열쇠 = 변수명 (키는 여러개가 될수있음 하지만 저장된 값은하나임) 

참조에 의한 비교

- 객체 비교시 동등 연산자 == 와 일치 연산자 ===는 동일하게 동작한다. 비교시 두객체가 동인할 객체인 경우에 true 반환

let a = {name: "marry"};
let b = a; // 참조에 의한 복사

console.log( a == b ); // true, 두 변수는 같은 객체를 참조합니다.
console.log( a === b ); // true
console.log(a) //{name: 'marry'}
console.log(b) //{name: 'marry'}

- 참조되지 않은 다른 두객체

let a = {name: "marry"};
let b = {name: "marry"}; // 독립된 두 객체

console.log( a == b ); // false
console.log( a === b ); // false
console.log(a) //{name: 'marry'}
console.log(b) //{name: 'marry'}

- 객체끼리의 대소 비교나 원시값과 객체를 비교하는 것이 필요한경우는 드물다. 코딩 실수 때문에 발생한다(데이터의 값을 확인 잘하자.)

객체복사

- 객체가 할당된 변수를 복사하면 객체에 대한 참조 값이 하나더 만들어 진다(서랍은 하나이고, 서랍을 열수 있는 열쇠는 여러개이다.)

- 객체 복제가 필요한 상황이라면 새로운 객체를 만든 다음 기존 객체의 프로퍼티들을 순회해 원시수준까지 프로퍼티를 복사하면 된다.

let user = {
  name: "John",
  age: 30
};

let clone = {}; // 새로운 빈 객체

// 빈 객체에 user 프로퍼티 전부를 복사해 넣습니다.
for (let key in user) {
  clone[key] = user[key];
}
console.log(clone) //{name: 'John', age: 30}

// 이제 clone은 완전히 독립적인 복제본이 되었습니다.
clone.name = "Pete"; // clone의 데이터를 변경합니다.
clone.age = 26
clone.isMarried = false

console.log( user.name ); // 기존 객체에는 여전히 John이 있습니다.
console.log( clone) // {name: 'Pete', age: 26, isMarried: false}

-  for in을 통해 clone 변수를 user객체와 같은 값을 참조하지 않고 독립적인 객체가 됨

object.assign

- Object.assign를 사용하는 방법도 있습니다.

- dest = 변경하기 위한 객체

- src1 ... srcN은 복사하고자 하는 객체

Object.assign(dest, [src1, src2, src3...])

예시

let user = { name: "John" };

let permissions1 = { canView: true };
let permissions2 = { canEdit: true };

// permissions1과 permissions2의 프로퍼티를 user로 복사합니다.
Object.assign(user, permissions1, permissions2);

console.log(user) // { name: "John", canView: true, canEdit: true }

혼자 해보기

let object = {
    name: 'jjangu',
    age: 5,
    hasMom: true
    
}

let friend1 = {friend1: "yuri"}
let friend2 = {friend2:"mangu"}

Object.assign(object, friend1, friend2)
console.log(object) // {name: 'jjangu', age: 5, hasMom: true, friend1: 'yuri', friend2: 'mangu'}

object.assing을 사용하면 반복문없이도 간단하게 객체를 복사 할 수 있다.

let user = {
  name: "John",
  age: 30
};

let clone = Object.assign({}, user);
clone.name = "jjangu"
console.log(clone) // {name:"jjangu", age: 30}
console.log(clone === user) //false

- user에 있는 모든 프로퍼티가 빈배열에 복사되고 변수에 할당된다 user와 clone은 같은 값을 참조하는 객체가 아닌 서로 다른 값을 참조하는 "완전히 다른 객체"가 된다.

중첩 객체 복사

- 객체의 프로퍼티가 다른객체에 대한 참조 값일 경우

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};

console.log( user.sizes.height ); // 182
console.log( user.sizes.width ); // 50
console.log( user.sizes ) // { height:182, width: 50}

clone.sizes = user.sizes로 프로퍼티를 복사하는 것만으론 객체를 복제할 수 없습니다. user.sizes는 객체이기 때문에 참조 값이 복사되기 때문입니다. clone.sizes = user.sizes로 프로퍼티를 복사하면 clone과 user는 같은 sizes를 공유하게 됩니다.

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};

let clone = Object.assign({}, user);

alert( user.sizes === clone.sizes ); // true, 같은 객체입니다.

// user와 clone는 sizes를 공유합니다.
user.sizes.width++;       // 한 객체에서 프로퍼티를 변경합니다.
console.log(clone.sizes.width); // 51, 다른 객체에서 변경 사항을 확인할 수 있습니다.

- user와 clone변수는 같은 값을 참조하고 있다. object.assing 메서드로 user변수를 clone 변수에 옮겼지만 같은 객체 값이 원시데이터가 아닌 객체이므로 참조 값이 분리되지 않는다.
- user변수와 clone변수를 각각 다른 객체로 분리하려면 user[key]의 각 값을 검사하면서 그값이 객체인 경우 객체의 구조도 복사해 주는 반복문을 사용해야 한다. 이런 방식을 깊은 복사(deep cloning) 라고한다.

참고 : 자바스크립트 라이브러리 lodash의 메서드인  _.cloneDeep(obj)를 사용하면 깊은 복사를 처리할 수 있다.

요약

  • 객체는 참조에 의해 할당되고 복사된다. 변수엔 객체 자체가 아닌 메모리상의 주소인 참조가 저장된다 따라서 객체가 할당된 변수를 복사하거나 함수의 인자로 넘길 땐 객체가 아닌 객체의 참조가 복사된다.
  • 복사된 참조를 이용한 모든 작업은 동일한 객체를 대상을 이뤄진다.
  • 객체의 진자 복사본을 만들려면 얕은 복사(shallow copy) 를  가능하게 해주는 Object.assing 메서드나 깊은 복사를 가능하게 해주는_.cloneDeep(obj)를 사용하면된다. 이때 얕은 복사는 중첩 객체(객체안의 객체)를 처리하지 못한다.얕은 복사를 해결하기 위해 또다른 방법은 for in 반복문을 통해 각 프로퍼티가 객체인지 판단하면서 객체구조일 경우 각 구조의 원시타입까지 가서 복제를 해주는 반복문을 사용해야한다 깊은 복사(Deep Cloning)

출처 및 참조

https://ko.javascript.info/object-copy

 

참조에 의한 객체 복사

 

ko.javascript.info

 

'Javascript' 카테고리의 다른 글

이벤트 루프  (0) 2023.07.19
new Date() 객체  (0) 2023.04.06
자바스크립트 화살표 함수  (0) 2023.04.05
자바스크립트 문자열 메서드 정리  (0) 2023.03.20
자바스크립트 배열 메서드정리  (0) 2023.03.19
  1. 객체복사
  2. 기본형(원시타입)
  3. 참조형(객체)
  4. 참조에 의한 비교
  5. 객체복사
  6. object.assign
  7. 예시
  8. 혼자 해보기
  9. 중첩 객체 복사
  10. 요약
'Javascript' 카테고리의 다른 글
  • 이벤트 루프
  • new Date() 객체
  • 자바스크립트 화살표 함수
  • 자바스크립트 문자열 메서드 정리
index.ys
index.ys
머리속에 떠도는 코드조각들을 맞추는 공간입니다.
index.ys
코린이 개발일지
index.ys
전체
오늘
어제

공지사항

블로그 메뉴

  • 홈
  • 방명록
  • Github
  • Notion
  • Figma
  • 타닥타닥 (235)
    • 개발일지 (124)
    • html , css (0)
    • Javascript (30)
    • Node.js (8)
    • React (2)
    • 네트워크 (1)
    • DB, SQL (5)
    • AWS (11)
    • CS (21)
    • 면접 (13)
    • 사진 (4)
    • 북로그 (3)
    • 머릿속 (5)

인기 글

최근 글

최근 댓글

hELLO · Designed By 정상우.
index.ys
객체복사
상단으로

티스토리툴바

개인정보

  • 티스토리 홈
  • 포럼
  • 로그인

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.