let score = 80;
let person = {name: ahn};
primitive 타입과 reference 타입의 자료형은 처음 선언할 때부터 차이가 드러난다.
primitive 타입 중 하나인 숫자형 80을 score
라는 변수에 저장할 땐 80이라는 수 자체가 메모리에 할당된다.
하지만 객체를 만들어 person이라는 변수에 할당하고자 했을 때 person에 할당 된 것은 객체 자체가 아닌, 객체에 접근할 수 있는 주소값인 모습이다.
이 상태에서 각 변수 score
, person
을 각각 copy
라는 새로운 변수에 할당해보자.
let copy = score;
let copy = person;
이 순간 일어나는 것은 엄밀히 말하자면 두 경우 모두 ‘값에 의한 복사 pass by value’이다. 용어 목차에서 정리했듯이, 값이란 변수에 저장된 데이터이기 때문이다. 왼쪽 경우에는 80이라는 값이 복사 되었고, 오른쪽 경우에는 0x00001332 라는 값이 복사된 것 뿐이다. 이를 두고 저자는 “자바스크립트에는 ‘참조에 의한 전달’은 존재하지 않고 ‘값에 의한 전달’만이 존재한다고 말할수 있다”고 서술해두었다. 새로운 변수에 값을 할당시 할당되는 값이 원시형 primitive type이냐, 참조형 reference tyepe이냐에 따라 두 방식을 구분지어 말하기 위한 용어이다.
객체를 복사함에 있어서 그 깊이의 차이를 나타낼 때 쓰는 용어로서의 얕은/깊은 복사
얕은 복사와 깊은 복사 모두 참조값이 원본과 다른 객체를 생성한다. 하지만 다른 점이 있다면 얕은 복사를 사용한 경우 객체 내부의 객체는 원본 참조값을 복사해오고, 깊은 복사는 객체 내부의 객체까지도 모두 원본 참조값과는 다른 객체로 복사해온다는 것이다.
const o = { x: { y: 1 } };
// 얕은 복사
const c1 = { ...o }; // 35장 "스프레드 문법" 참고
console.log(c1 === o); // false
console.log(c1.x === o.x); // true
// lodash의 cloneDeep을 사용한 깊은 복사
// "npm install lodash"로 lodash를 설치한 후, Node.js 환경에서 실행
const _ = require('lodash');
// 깊은 복사
const c2 = _.cloneDeep(o);
console.log(c2 === o); // false
console.log(c2.x === o.x); // false
(위에서 약속한 뜻을 가진) 참조에 의한 복사 pass by reference, 값에 의한 복사 pass by value를 표현하는 또 다른 용어로서의 얕은/깊은 복사
const v = 1;
// "깊은 복사"라고 부르기도 한다.
const c1 = v; // pass by value
console.log(c1 === v); // true
const o = { x: 1 };
// "얕은 복사"라고 부르기도 한다.
const c2 = o; // pass by reference
console.log(c2 === o); // true