[자바스크립트] 객체 복사

hyeon·2024년 10월 10일

객체의 얕은 복사와 깊은 복사를 알아보고, 실제로 구현해본다. 마지막에는 직접 구현하지 않고, API를 활용하는 방법도 알아볼 것이다.

1. 얕은 복사

var copyObject = function (target) {
  var result = {};

  for (var prop in target) {
    result[prop] = target[prop];
  }
  return result;
};

var user = {
  name: "wonjang",
  gender: "male",
};

var user2 = copyObject(user);
user2.name = "twojang";

if (user !== user2) {
  console.log("유저 정보가 변경되었습니다.");
}

console.log(user.name, user2.name);
console.log(user === user2);

코드결과)
유저 정보가 변경되었습니다.
wonjang twojang
false

객체를 얕은복사하는 방법은 위와 같지만, 추천하지는 않는다.
왜냐면, 중첩된 객체에 대해서는 완벽한 복사를 할 수 없기 때문이다.

정리)

  • 얕은 복사: 개체의 최상위 속성만 복사(위의 예제)
  • 문제점: 중첩된 객체의 경우 참조형 데이터가 저장된 프로퍼티를 복사할 때,
    주소값만 복사하기 때문에, 복사본에서 중첩된 객체를 변경하면 원본에 영향을 미친다.

2. 깊은 복사

깊은 복사 : 각 내부 값을 탐색하고 모든 요소를 완전하고 독립적으로 복제

// 깊은 복사
var copyObjectDeep = function (target) {
  var result = {};

  if (typeof target === "object" && target !== null) {
    for (var prop in target) {
      result[prop] = copyObjectDeep(target[prop]);
    }
  } else {
    result = target;
  }
  return result;
};

//결과 확인
var obj = {
  a: 1,
  b: {
    c: null,
    d: [1, 2],
  },
};
var obj2 = copyObjectDeep(obj);

obj2.a = 3;
obj2.b.c = 4;
obj2.b.d[1] = 3;

console.log(obj);
console.log(obj2);

코드결과)
{ a: 1, b: { c: null, d: [ 1, 2 ] } }
{ a: 3, b: { c: 4, d: { '0': 1, '1': 3 } } }

결론 : 객체의 프로퍼티 중에서 기본형 데이터는 그대로 복사하고,
참조형 데이터는 다시 그 내부의 프로퍼티를 복사한다. => 어떻게? (재귀적 수행으로...)


3. StructuredClone()

사실 깊은 복사는 실무에서 잘 사용하지 않고, API를 많이 활용한다.
그래서 객체를 복사하는 API를 가져왔다.

JavaScript의 structuredClone() 메서드는 객체의 전체 복사본을 생성한다. 즉, 참조만 복사하는 것이 아니라 객체와 객체의 모든 중첩 속성을 복제한다. 이는 데이터 구조가 복잡하거나 깊이 중첩되어 있더라도 원본 개체에 영향을 주지 않고 개체의 완전히 독립적인 복제본을 생성하려는 경우에 유용하다.

const person = {
  name: "John",
  details: {
    age: 30,
    location: "Seoul",
  },
};

// deep copy
const copyOfPerson = structuredClone(person);

// 복제본에서 중첩된 객체 내용 변경
copyOfPerson.details.age = 25;

console.log(person.details.age);
console.log(copyOfPerson.details.age);

코드결과)
30
25

profile
당근🥕

0개의 댓글