[javascript] 얕은 복사 (참조 복사), 깊은 복사(값 복사)

728x90
반응형

 

출처: 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

 

wanna-b.tistory.com/18

 

이 글은 위 글을 공부하면서 제가 기록한 글입니다.

 

자바스크립트 값의 타입은 원시 타입과 참조 타입이 있다

 

원시타입 참조타입 
  • number
  • string
  • boolean
  • null
  • undefined
  • object
  • symbol

 

1. 깊은 복사, 값 복사 (Deep Copy, 실제로 새로운 변수와 값을 만들어내는 복사)

 

원시값은 새로운 배열에 같은 값을 새로 생성(!)해서 그 값을 새로운 변수에 할당한다

 

let a=100;
let b=a;

a=200;
console.log(a); //200
console.log(b); //100

새로운 값이 복사되어 생성되고 새로운 변수에 할당되었다! 두 변수는 독립적이다

위처럼 두 변수가 완전히 독립적인 복사가 값 복사 혹은 깊은 복사라고 한다

 

 

깊은 복사, 값 복사 Deep copy를 하는 방법 (재귀, 반복 함수 복사(for - in), JSON.stringify ())

 

객체 안의 객체도 기존 객체를 참조하는 게 아니라 새롭게 만들어지는 복사이다

 

1. 재귀함수 복사, 반복문 복사 (for in)

 

function clone(obj){
	let result={};
    for (let i in obj){
    result[i]=obj[i];
    }
    return result;
    }
    
   
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

obj.b.c === copiedObj.b.c //false 

2. JSON.stringify()

 

객체를 json형태의 문자열로 변환하면서 참조가 끊긴다. 다시 JSON.parse()를 이용해 객체로 만들어준다

 

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

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

copiedObj.b.c = 3

obj.b.c === copiedObj.b.c //false 

 

3. lodash 라이브러리 사용

 

2. 얕은 복사, 참조 복사 (Shallow Copy, 기존의 변수가 가르키는 곳을 똑같이 참조하는 복사)

 

참조값은 변수가 메모리에 저장된 값을 가르키는 참조이다.

새로운 변수에 복사하면 해당 메모리를 가르키는 같은 참조가 할당되기 때문에 값을 바꾸면 기존 변수와 새로운 변수값 모두가 바뀌게 된다. (같은 곳을 가르키고 있으므로)

 

참조값은 기존 변수 값도 같이 바뀌어버린다

이를 참조 복사 혹은 얕은 복사라고 한다

const a={name:'sara'};

const b=a;
b.name='new!';

console.log(a.name); // new!

 

얉은 복사는 객체를 복사할 때 기존 값과 새로 복사한 변수의 값이 같은 참조를 가르킨다

객체안의 프로퍼티로 객체가 있을 경우 내부 객체까지 새로운 값이 되진 않는다

(내부 객체는 기존 객체의 참조값을 갖게된다)

새 배열의 값을 바꾸면 기존 배열의 값도 같은 곳을 참조하므로 바뀌게 된다

 

얉은 복사, 참조 복사 (Object.assign(), spread operator)를 하는 방법 

 

1. Object.assign()

첫 번째 파라미터로 만들 객체의 default형태를 넣어주고 두 번째 파라미터에 추가할 부분을 넣어준다. 

첫 번째 파라미터의 객체의 두 번째 값이 덮여씌워지거나 추가된다

 

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

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

copiedObj.b.c = 3

obj === copiedObj // false 겉의 객체는 다른 객체가 생성되었지만 
obj.b.c === copiedObj.b.c // true 내부의 객체는 여전히 기존 객체를 참조하고 있다

2. spread operator 

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

const copiedObj = {...obj}

copiedObj.b.c = 3

obj === copiedObj // false
obj.b.c === copiedObj.b.c // true

 

 

 

 

728x90
반응형
TAGS.

Comments