반응형
Notice
Recent Posts
Recent Comments
Link
관리 메뉴

짧은코딩

얕은 복사와 깊은 복사 본문

JS

얕은 복사와 깊은 복사

5_hyun 2022. 11. 17. 18:43
반응형

객체의 특징

객체는 복사할 때 원시 타입(문자열, 숫자, 불린값)가 다른 방식을 사용한다.

 

객체를 아래 코드처럼 복사하게 되면

let user = { name: "John" };

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

 참조 값을 복사하게 된다.

 

이는 user에서 객체를 저장하고 있는 위치를 admin에게 알려줘서 참조값을 복사하는 것이다. 

이렇게 된다면 admin을 수정했을 때, user의 값도 바뀌게 된다.

그리고 user와 admin을 '==', '===' 연산자로 비교하면 true가 나오게 된다. (객체는 '=='도 '==='와 동일하게 동작)

 

얕은 복사

얕은 복사는 객체를 복사할 때 기존 값과 복사된 값이 같은 참조를 가리키는 것을 말한다. 객체 안의 한 객체라도 기존 변수의 객체를 참조하고 있으면 이를 얕은 복사라고 한다.

 

1. Object.assign

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = Object.assign({}, obj);

copiedObj.b.c = 3;

console.log(obj === copiedObj); // false
console.log(obj.b.c === copiedObj.b.c); // true

Object.assign(a, b)는 a 객체에 b 객체를 복사해주는 것이다. 

obj와 copiedObj는 서로 다른 객체에 복사된 것이라 서로 독립적인 복제본이 되었지만 안의 b 객체는 서로 같은 값을 참조하고 있다. 

 

2. 스프레드 연산자

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = {...obj}

copiedObj.b.c = 3

console.log(obj === copiedObj); // false
console.log(obj.b.c === copiedObj.b.c) // true

여기서도 마찬가지로 obj와 copiedObj의 b 객체는 같은 값을 참조하고 있어서 위 같은 결과가 나온다.

깊은 복사

깊은 복사된 객체는 객체안에 객체가 있어도 원본과 참조가 완전 끊긴 객체를 의미한다.

 

1. 재귀함수를 이용한 복사

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

function copyObj(obj) {
  const result = {};

  for (let key in obj) {
    if (typeof obj[key] === "object") {
      result[key] = copyObj(obj[key]);
    } else {
      result[key] = obj[key];
    }
  }

  return result;
}

const copiedObj = copyObj(obj);

copiedObj.b.c = 3;

console.log(obj.b.c === copiedObj.b.c); //false

이 코드처럼 재귀함수를 이용해서 복사하면 두 객체간의 참조가 끊겨서 "obj.b.c === copiedObj.b.c"의 결과가 false가 나온다.

 

2. _.cloneDeep

var objects = [{ 'a': 1 }, { 'b': 2 }];
 
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false

 js의 lodash의 메서드인 _.cloneDeep를 사용하면 반복문을 사용하지 않아도 깊은 복사를 할 수 있다.

 

3. JSON.stringify()

const obj = {
  a: 1,
  b: {
    c: 2,
  },
};

const copiedObj = JSON.parse(JSON.stringify(obj));

copiedObj.b.c = 3;

console.log(obj.b.c === copiedObj.b.c); //false

객체를 json으로 변경하는 과정에서 참조가 모두 끊긴다. JSON.parse()를 이용해 다시 객체로 만들어주면 깊은 복사가 된다.

 

-참고 사이트

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

 

참조에 의한 객체 복사

 

ko.javascript.info

https://velog.io/@th0566/Javascript-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC

 

[Javascript] 얕은 복사, 깊은 복사

자바스크립트에서 값은 원시값과 참조값으로 나뉜다. 원시값 Number String Boolean Null Undefined 참조값 Object Symbol 원시값은 값을 복사 할 때 복사된 값을 다른 메모리에 할당 하기 때문에 원래의 값과

velog.io

 

반응형

'JS' 카테고리의 다른 글

변수 호이스팅과 값의 할당  (0) 2023.08.25
"forEach" vs "map"  (0) 2023.07.13
async와 await  (0) 2022.06.03
Promise  (0) 2022.06.03
자바스크립트-심볼형  (0) 2022.05.15
Comments