nestd object 란?
아래처럼 중첩된 object를 말한다.
// nested Object
const a = {
b : 100,
c : {
d : 1,
e ; 2
}
}
//nested Array
const b = [{a:1, b:2}, {c:3}]
const c = [[a,b],[c,d]]
shallow copy & deep copy
object(array)를 copy할 때는 shallow copy와 deep copy가 있다.
shallow copy 방법을 사용하면 해당 object의 property 자체를 복사하는게 아니라, reference를 복사하게된다.
따라서 새로 copy한 object에서 무언가 바꾸면 원래 object에서도 바뀐다.
이렇게 하지 않고 실제로 복사한 것을 deep copy라고 한다.
shallow copy 예시
const a = [1,2,3];
const b = a;
b[1] = 100;
console.log(a); //[1,100,3]
console.log(b); //[1,100,3]
deep copy 예시
//Using Object.assign
const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };
const returnedTarget = Object.assign(target, source);
console.log(target);
// expected output: Object { a: 1, b: 4, c: 5 }
console.log(returnedTarget);
// expected output: Object { a: 1, b: 4, c: 5 }
//Using ES6 spread operation
const a = [1,2,3];
const b = [...a]
b[1] = 100;
console.log(a); //[1,2,3]
console.log(b); //[1,100,3]
그런데 이때, nested Object에서 spread operation을 사용하면 deep copy 되지 않는 것을 발견할 수 있다.
const c = [{a : 1, b: 2}, {c:3, d:4}];
const d = [...c];
const e = Object.assign(c, []);
d.forEach(val => val.a = 100);
console.log(c);
console.log(d);
e[0].a = 200;
console.log(e);
c, d, e 모두 a의 값이 변했다.
Nested Object Deep Copy
nested object에서 deep copy를 하는 방법은 크게 두가지가 있다.
1. 외부라이브러리사용
2. JSON으로 변환 후 Object로 다시 변환
1의 경우 lodash, Ramda, rfdc (Really Fast Deep Clone) 등이 있다.
많은 nested object를 deep copy해야하는경우 rfdc를 추천한다. 성능이 가장 좋다고 한다.
2는 아래와 같다.
const arr = [{a:1, b:2}, {c:3, d:4}];
const clone = JSON.parse(JSON.stringify(arr));
하지만 이 방법은 별로 추천되지 않는다. stringify과정에서 date등의 타입이 모두 string으로 변해버리기 때문이다. 이럴 염려가 없는 데이터만 가지고 있다면 써도 괜찮다.
// Only some of these will work with JSON.parse() followed by JSON.stringify()
const sampleObject = {
string: 'string',
number: 123,
boolean: false,
null: null,
notANumber: NaN, // NaN values will be lost (the value will be forced to 'null')
date: new Date('1999-12-31T23:59:59'), // Date will get stringified
undefined: undefined, // Undefined values will be completely lost, including the key containing the undefined value
infinity: Infinity, // Infinity will be lost (the value will be forced to 'null')
regExp: /.*/, // RegExp will be lost (the value will be forced to an empty object {})
}
console.log(sampleObject) // Object { string: "string", number: 123, boolean: false, null: null, notANumber: NaN, date: Date Fri Dec 31 1999 23:59:59 GMT-0500 (Eastern Standard Time), undefined: undefined, infinity: Infinity, regExp: /.*/ }
console.log(typeof sampleObject.date) // object
const faultyClone = JSON.parse(JSON.stringify(sampleObject))
console.log(faultyClone) // Object { string: "string", number: 123, boolean: false, null: null, notANumber: null, date: "2000-01-01T04:59:59.000Z", infinity: null, regExp: {} }
// The date object has been stringified, the result of .toISOString()
console.log(typeof faultyClone.date) // string
참고
https://javascript.plainenglish.io/how-to-deep-copy-objects-and-arrays-in-javascript-7c911359b089
'javascript' 카테고리의 다른 글
[javascript] Promise, Async, Await, fetch, axios (0) | 2022.07.06 |
---|---|
[JavaScript]ES6, Arrow Function, ES6 Method, Method (0) | 2022.06.20 |
[javascript] super의 역할 (0) | 2022.04.07 |
[javascript] 프로토타입 섀도잉, 오버리이딩 (0) | 2022.04.07 |
[javascript] 상속, class, extends키워드 (0) | 2022.04.06 |