객체의 얕은 복사 (Shallow Clone)
Object.assign()
첫번째 인자로 들어온 객체에 두번째 인자로 들어온 객체의 프로퍼티들을 복사해서 넣는다.
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}
Spread Operator
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()과 기능은 동일하다.
for문을 통해 순서대로 복사
const copyFunc = (obj) => {
let copiedObj = {};
for (let key in obj) {
copiedObj[key] = obj[key];
}
return copiedObj;
};
const original = {
a: 1,
b: 2,
c: {
d: 3,
},
};
const result = copyFunc(original);
original.a = 100;
original.c.d = 3000;
console.log(result.a); // 1
console.log(result.c.d); // 3000
세 가지 방법 다 복사한 객체 안의 객체 요소는 주소를 참조하기 때문에 원본과 함께 값이 변경된다.
이를 방지하기 위해서는 깊은 복사가 필요하다.
객체의 깊은 복사 (Deep Clone)
JSON 객체의 메소드 이용하기
const cloneObj = (obj) => JSON.parse(JSON.stringify(obj));
const original = {
a: 1,
b: {
c: 2,
},
};
const copied = cloneObj(original);
original.a = 1000;
original.b.c = 2000;
console.log(copied.a); // 1
console.log(copied.b.c); // 2
JSON.stringify는 자바스크립트 객체를 JSON 문자열로 변환시킨다.
그리고 JSON.parse는 JSON 문자열을 자바스크립트 객체로 변환시킨다.
위 방법을 사용하면 객체를 문자열로 치환했다가 다시 객체로 변환했기 때문에 객체에 대한 참조가 없어진다.
하지만 이 방법은 성능적으로 느리고, JSON.stringify 메소드가 function을 undefined로 처리한다는 문제가 있다.
Lodash의 cloneDeep() 메소드 이용하기
Lodash는 많은 사람들이 사용해오고 있으며, 안정성이 증명된 라이브러리이다.
Lodash의 많은 메소드들 중에서 cloneDeep() 메소드를 사용하면 깊은 복사가 가능하다.
<script src="https://raw.githubusercontent.com/lodash/lodash/4.17.15-npm/lodash.min.js"></script>
npm i --save lodash
Lodash 라이브러리를 사용하려면 위와 같은 방법이나 다른 방법들을 사용해서 설치를 먼저 해야 한다.
const - = require('lodash');
obj = {
a: 10,
b: {
aa: "abc",
},
};
newObj = _.cloneDeep(obj);
obj === newObj; // false
obj.a === newObj.a; // false
obj.b === newObj.b; // false
재귀적으로 직접 구현하기
function deepClone(obj) {
if (obj === null || typeof obj !== "object") {
return obj
}
const result = Array.isArray(obj) ? [] : {}
for (let key of Object.keys(obj)) {
result[key] = deepClone(obj[key])
}
return result
}
const original = {
a: 1,
b: {
c: 2,
},
d: () => {
console.log("hi")
},
}
const copied = deepClone(original)
original.a = 1000
original.b.c = 2000
original.d = () => {
console.log("bye")
}
console.log(copied.a) // 1
console.log(copied.b.c) // 2
console.log(copied.d()) // 'hi'
'JavaScript > Vanilla' 카테고리의 다른 글
고차함수 (0) | 2021.07.27 |
---|---|
DOM (Document Object Model) (0) | 2021.07.24 |
Hoisting (0) | 2021.07.24 |
Spread와 Rest 문법 (0) | 2021.07.24 |
Closure가 어렵다면 내 탓이 아니라 JS 탓이다! (0) | 2021.07.22 |