본문 바로가기
Frontend/Javascript

Javascript 얕은 복사, 깊은 복사

by 우보틀 2022. 3. 27.

via GIPHY

 

얕은 복사(shallow copy)

 

변수가 가리키는 주소값이 같은 주소 값을 가리킬때 얕은 복사가 이루어진다고 한다.

reference type을 복사할때 얕은 복사가  이루어진다.

const a = { c: 'c' }
const b = a
b.c = 'd'

console.log(a) // { c: 'd' }
console.log(b) // { c: 'd' }
console.log(Object.is(a,b)) // true

 

spread를 통한 복사는 1 depth 까지만 깊은복사가 이루어진다.

const a = { b: { c: 'c' }, e: 'e' }
const b = {...a}

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'z' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }

위의 코드를 보면 1depth인 e 값을 바꾸면 b의 값만 바뀌지만 

key 값이 b의 c의 값을 바꾸면 a 변수의 값도 바뀌어 버린다.

1 depth 까지만 깊은 복사가 이루어 지는 것이다.

 

Object.assign을 통한 복사 또한 1 depth 까지만 깊은 복사가 이루어진다.

const a = { b: { c: 'c' }, e: 'e' }
const b = Object.assign({}, a)

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'z' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }

 


깊은 복사(deep copy)

원시 타입의 복사는 기본적으로 깊은 복사이다.

const a = 'a'
const b = a

원시타입을 복사하게 되면 b 변수에는 새로운 주소에 같은 값이 할당된다

 

깊은 복사를 하기 위해서는

 

커스텀 함수를 사용하거나 

const deepCopy = (target, temp) => {
  for (let key in target) {
  	if (typeof target[key] === 'object') {
      deepCopy(target[key], temp[key] = {})
    } else {
      temp[key] = target[key]
    }
  }
  return temp;
}

const a = { b: { c: 'c' }, e: 'e' }
const b = deepCopy(a, {})

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }

라이브러리를 사용하거나 (ex. lodash의 deep copy)

 

JSON.parse(Json.Stringify(Object))) 를 사용한다.

const a = { b: { c: 'c' }, e: 'e' }
const b = JSON.parse(JSON.stringify(a))

console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'e' }


b.e = 'd'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'c' }, e: 'd' }

b.b.c = 'z'
console.log(a) // { b: { c: 'c' }, e: 'e' }
console.log(b) // { b: { c: 'z' }, e: 'd' }

'Frontend > Javascript' 카테고리의 다른 글

Javascript 함수 => 1급 객체 ❓  (0) 2022.04.01
Javascript event loop  (0) 2022.03.31
Javascript Polyfill  (0) 2022.03.26
Javascript strict mode  (0) 2022.03.25
Javascript 화살표 함수  (0) 2022.03.25