원시값을 할당한 변수를 참조하면 메모리에 저장된 원시 값에 접근하고 객체를 할당한 변수를 참조하면 메모리에 저장된 참조 값을 통해 실제 객체에 접근한다.
string
boolean
number
undefined
null
원시 값 자체를 값으로 갖는다. 각 변수간 데이터값이 복사되기때문에 기존값 영향 x
배열
객체
변경 가능한 값, 원시 값을 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하여 원시 값에 접근한다. 생성된 객체가 저장된 메모리 공간의 주소 그자체
let arr = [0, 1, 2, 3];
let copiedArr = arr.slice();
console.log(copiedArr); // [0, 1, 2, 3]
console.log(arr === copiedArr); // false
배열 요소는 같지만 참조하는 주소가 다름
copiedArr.push(4);
console.log(copiedArr); // [0, 1, 2, 3, 4]
console.log(arr); // [0, 1, 2, 3]
주소가 달라서 복사한 배열에 요소를 추가해도 원본은 바뀌지 않음
let arr = [0, 1, 2, 3];
console.log(...arr); // 0 1 2 3
다른 주소를 참조하며 같은 요소를 가지고 있게 배열을 복사
let obj = { firstName: "jungo", lastName: "m" };
let copiedObj = Object.assign({}, obj);
console.log(copiedObj) // { firstName: "jungo", lastName: "m" }
console.log(obj === copiedObj) // false
다른 추소를 참조하며 같은 요소를 가지고 있기 배열을 복사
배열과 마찬가지로 let copiedObj = {...obj};
로 복사
참조 자료형 내부에 참조 자료형이 중첩되어 있는 경우, slice()
Object.assign()
spread
syntax
를 사용해도 중첩된 구조는 복사할 수 x 한단계만 가능
참조 자료형 내부 중첩된 참조 자료형 까지 모두 복사하는 것
JSON.stringify()
는 참조 자료형을 문자열 형태로 변환하고, JSON.parse()
는 문자열의 형태를 객체로 변환하여 반환
const arr = [1, 2, [3, 4]];
const copiedArr = JSON.parse(JSON.stringify(arr));
console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false
중첩된 참조 자료형 중에 함수가 포함되어 있을 경우 위 방법을 사용하면 함수가 null로 바뀌게 되어 완전한 깊은 복사 방법이라고 보기 어렵다.
lodash
, ramada
설치
const lodash = require('lodash');
const arr = [1, 2, [3, 4]];
const copiedArr = lodash.cloneDeep(arr);
console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false