2020. 1. 30. 17:45ㆍ🔴 FE/JavaScript
흔히 하는 실수 '=' 연산자 사용
let origin = { num : 1 }
let clone = origin
origin.num = 2
console.log(clone) // { "num" : 2 }
객체는 '참조타입(reference type)'이기 때문에 객체를 '='로 복사하면 값이 아니라 메모리 주소값 참조를 복사한다.
즉, clone과 origin는 같은 메모리를 사용한다는 것이다.
그러므로 콘솔에 찍어보면 하나의 객체가 2개의 변수에 의해서 공유되고 있는걸 확인할 수 있다.
(하나의 변수를 통해 값을 바꿨지만, 다른 변수의 값도 함께 바뀌었다)
console.log(origin === clone)
따라서, 객체를 비교할 때 참조가 같은지 비교하는 '===, =='로 비교해보면 'true'라는 결과가 나온다.
얕은 복제 (Shallow Clone)
1. Object.assign(target, ...sources)
let clone = Object.assign({}, origin)
console.log(origin === clone) // false
해당 함수를 쓰면 첫번째 인자({})로 두번째 인자의 속성들을 복사할 수 있다
비교를 해보면 'false'라고 뜨며, 값을 바꿔도 서로 영향을 주지 않는다.
BUT, 그 값이 단순 속성이 아니라 객체나 배열리면 여전히 서로 영향을 끼친다
let origin = {
innerObj : {
x : 1,
y : 2
}
}
만약 origin 속의 innerObj속성이 객체라면?
console.log(origin.innerObj === clone.innerObj) // true
같은 주소값을 참조하고 있는 것을 확인할 수 있다.
이는 Object.assign()메서드가 "객체 트리의 최상위 레벨의 속성만 복사"하기 때문에 이런 현상이 나타나는 것이다.
2. ... (Spread Operator)
let clone = {...origin}
console.log(origin.innerObj === clone.innerObj) // true
Spread Operator를 사용하여 의도적으로 얕은 복제를 할 수 있다.
깊은 복제 (Deep Clone)
앞서 살펴봤듯이, 얕은 복제는 최상위의 속성만 복제하기 때문에 '깊은' 복제를 하려면 객체 트리의 제일 아래까지 복제해줘야 한다는 것을 알 수 있다. 재귀 함수를 만들어 최말단까지 복제할 수 있지만, 직접 구현하는 것보다 'lodash'오픈소스를 사용하는 것이 더 편리하다.
https://lodash.com/docs/4.17.15#clone
1. _.clone(value)
lodash에서 제공하는 얕은 복제 함수이다.
import * as _ from 'lodash';
var objects = [{ 'a': 1 }, { 'b': 2 }];
var shallow = _.clone(objects);
console.log(shallow[0] === objects[0]);
// => true
2. _.cloneDeep(value)
깊은 복제를 위해 우리는 cloneDeep함수를 사용하면 된다. 이 함수는 재귀적으로 value를 복제해준다.
import * as _ from 'lodash';
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
+ 이 외에도 "JSON.parse(JSON.stringify(origin))" 으로 깊은 복제를 할 수 있다고 하지만
string으로 바꿨다가 다시 parse할 때 만약 function이 속성으로 있다면 적합하지 않다고 한다.
참고:
'🔴 FE > JavaScript' 카테고리의 다른 글
움짤로 보는 자바스크립트 동작 원리(5) - Promises & Async/Await (8) | 2020.05.25 |
---|---|
움짤로 보는 자바스크립트 동작 원리(4) - Generators and Iterators (4) | 2020.05.19 |
움짤로 보는 자바스크립트 동작 원리(3) - Scope (Chain) (0) | 2020.05.14 |
움짤로 보는 자바스크립트 동작 원리(2) - Hoisting (0) | 2020.05.14 |
움짤로 보는 자바스크립트 동작 원리(1) - Event Loop (4) | 2020.05.14 |