[JavaScript] 객체의 복사

김호준·2021년 11월 6일
0

JavaScript 의 객체 복사

  • JS의 객체는 Key와 Value의 1개 또는 여러 쌍으로 구성되어 있다.
    • 여기서 Value에는 값이 아닌 또 다른 객체도 넣을 수 있다.

1. 참조할당

  • 참조 할당은 가장 쉽고 가장 먼저 떠오르는 방법으로 간단하지만 참조된 객체의 값을 변경하면 복사된 객체의 값 또한 변경된다.
const original = { a: 1, b: 2 }

const copied = original
original.a = 1000

console.log(copied.a) //1000
  • original과 copied 라는 서로 다른 변수가 같은 객체를 바라보고 있는 것이다.

2. 얕은 복사 ( Shallow Clone )

Object.assign()

  • 첫번째 인자로 들어오는 객체에다 두번째로 들어오는 객체의 Properties를 복사하는 것이다.
const obj = { a: 1, b: 2 }
const target = { c: 3 }

const copiedObj = Object.assign(target, obj)

console.log(copiedObj) //{c: 3, a: 1, b: 2}
  • 하지만 Object.assign()에서도 복사하려는 객체의 내부에 객체가 있다면 내부에 존재하는 객체는 완벽한 복사가 이루어지지 않는다는 점이다.
const person = {
  age: 100,
  name: {
    first: "junwoo",
    last: "park",
  },
}

const copied = Object.assign({}, person)

person.age = 1000
person.name.first = "paul"

console.log(copied.age) // 100
console.log(copied.name.first) // 'paul'
  • 위의 예시처럼 복사한 객체의 Properties는 완벽히 복사되었지만 객체 내부에 있는 객체는 완벽히 복사되지 않아 값을 변경하면 같이 변경된다.

ES6 Spread Operator

  • Spread Operator 도 Object.assign()과 같은 복사를 진행한다.
const original = {
  a: 1,
  b: 2,
  c: {
    d: 3,
  },
}

const copied = { ...original }

original.a = 1000
original.c.d = 3000

console.log(copied.a) // 1
console.log(copied.c.d) // 3000
  • Object.assign() 처럼 객체 내부의 객체는 완벽하게 복사하지 못한다는 단점을 가지고 있다.

깊은복사 ( Deep Clone )

  • 깊은 복사를 하는 방법에는 JSON의 메소드를 이용하거나 Lodash의 DeepClone 메소드를 이용하는 방법 2가지가 있다.

JSON 객체의 메소드 이용

  • JSON.parse(JSON.stringify( 복사할 객체 )); 처럼 사용한다.
const cloneObj = obj => JSON.parse(JSON.stringify(obj))

const original = {
  a: 1,
  b: {
    c: 2,
    cc: 3
  },
  d: () => {
    console.log("hi")
  },
}

const copied = cloneObj(original)

console.log(copied.b) 		// 	{ c:2, cc:3 }
console.log(copied.d) 		// undefined
  • JSON의 stringify메소드는 JS 객체를 JSON 문자열로 변환시킨 이후 JSON의 parse 메서드를 통해 다시 JS 객체로 변환하는 방법이다.

  • 하지만 JSON 방법은 성능적으로 느리다는 단점과 위의 예시에서 copied.d 처럼 JSON.stringify 메서드가 function을 undefined로 처리한다는 단점을 가지고 있다.

Lodash의 deepClone 메서드

const clonedeep = require("lodash.clonedeep")

const original = {
  a: 1,
  b: {
    c: 2,
  },
  d: () => {
    console.log("hi")
  },
}

const deepCopied = clonedeep(original)

original.a = 1000
original.b.c = 2000

console.log(deepCopied.a) // 1
console.log(deepCopied.b.c) // 2
console.log(deepCopied.d()) // 'hi'
profile
Go-getter Developer

0개의 댓글