처음 MDN에서 공부를 할 때 이해되지 않는 부분 투성이었지만, 그 중에서도 얕은 복사와 깊은 복사의 의미를 알지 못하고 알고리즘 퀴즈를 풀기에 급급했다. 프로토타입을 공부하면서 약간 알 것 같은 상태가 되었는데, 프로토타입의 개념이 간단하지 않기 때문에 그 과정에서 알게 된 복사의 두 가지 개념을 우선 정리해 보기로 했다.
잘못된 게 있다면 누구든 알려주시길 바라요.
레퍼런스 :
제로초TV https://youtu.be/BSReDRBjbp0
영어로는 얕은 복사(shallow copy), 깊은 복사(deep copy) 라고 표현 하는데 둘을 간단히 구분하면,
얕은 복사 : 참조
깊은 복사 : 복사
원시타입(문자, 숫자, 논리값)은 복사(깊은복사)가 되고
원시타입을 제외한 객체들(배열, 오브젝트, 함수)은 참조(얕은복사)가 된다.
즉 데이터의 타입에 따라 다루는 방법이 다르다. 비교해서 코드를 써보면,
let a = 100; //숫자는 원시타입
let b = a; //이것은 복사 입니다.
console.log(a); //100
console.log(b); //100
//여기서 a를 변경하면,
a = 200;
console.log(a); //200 a의 값만 변경됨.
console.log(b); //100
let a = { name: '하루'};
let b = a; //이것은 객체이므로 참조가 됩니다.
console.log(a); //{name: "하루"}
console.log(b); //{name: "하루"}
//a의 값을 변경하게 되면,
a.name = '바보';
console.log(a); //{name: "바보"}
console.log(b); //{name: "바보"} b도 영향을 받게 된다는 것!
그럼 객체는 깊은 복사를 할 수 없는걸까?
몇 가지 복잡한 방법들이 있지만 말 그대로 복잡하거나 성능이 나쁜 이슈가 있다고 한다.
간단하게 복사하는 방법으로 한 가지는 Object.keys()를 활용하는 것. 하지만 이것도 하위 객체가 존재하면 그 안에서는 먹히지 않은 불완전한 복사 방법이다.
let obj1 = { a: 1, b: 2, c: { d: 3}} //이렇게 뎁스를 가진 객체의 경우
let obj2 = {}; //내용을 복사할 빈 갠체를 만들고
//Object.keys()메서드로 키 값을 복사
Object.keys(obj1).forEach(function(key) {
obj2[key] = obj1[key];
});
console.log(obj1); //{ a: 1, b: 2, c: { d: 3}}
console.log(obj2); //{ a: 1, b: 2, c: { d: 3}}
obj1.a = 0; //obj1의 a값을 0으로 변경하면
console.log(obj1.a); //0 이 경우 1 단계 데이타들은 복사되어 obj1의 값만 변경됨
console.log(obj2.a); //1
obj1.c.d = 4; //하지만 obj1의 d값을 변경하면
console.log(obj1.c.d); //4
console.log(obj2.c.d); //4 obj2의 d값도 변경이 된다!!
뎁스를 극복하기 위해 JSON.parse(), JSON.stringify() 메서드를 활용할 수 있는데 성능이슈가 크기 때문에 실무에서는 피한다고..
let obj1 = { a: 1, b: 2, c: { d: 3}};
let obj2 = JSON.parse(JSON.stringify(obj1));
console.log(obj1); //{ a: 1, b: 2, c: { d: 3}}
console.log(obj2); //{ a: 1, b: 2, c: { d: 3}}
obj1.c.d = 4; //위와 동일한 방법으로 d값을 바꾸면
console.log(obj1); //{ a: 1, b: 2, c: { d: 4}} obj1만 변경됨
console.log(obj2); //{ a: 1, b: 2, c: { d: 3}}
객체의 뎁스가 깊어질수록 헷갈릴 것 같다. 다른 방법이 있겠지?
오늘은 여기까지.
'Coding > TIL (Today I Learned)' 카테고리의 다른 글
npm, Package.json (0) | 2019.11.29 |
---|---|
Javascript runtime, Node.js, NVM (0) | 2019.11.28 |
[Reference] 현직 개발자들의 이야기 (0) | 2019.11.27 |
JavaScript ES5 와 ES6 달라진 점 01 (0) | 2019.11.16 |
Git 01. 풀리퀘스트(pull request) 방법 (0) | 2019.11.14 |