원시 타입 값은 변경 불가능한 값
객체(참조) 타입의 값은 변경 가능한 값
한번 생성된 원시 값은 읽기 전용 값으로서 변경할 수 없다. 변경 불가능하다는 것은 변수가 아니고 값에 대한 진술이다. 즉, 원시 값 자체를 변경할 수 없다는 뜻이지 변수 값을 변경할 수 없는 것은 아니다.
✅ 변수의 상대 개념인 상수는 재할당이 금지된 변수지만, 변경 불가능한 값은 아니다.
문자열은 다른 원시 값과 비교할 때 한가지 특성이 있는데, 몇개의 문자로 이뤄지냐에 따라서 필요한 메모리 공간이 다르다.
유사 배열 객체
마치 배열처럼 인덱스로 프로퍼티에 접근가능하며, length 프로퍼티를 갖는 객체를 뜻한다.
let str = 'string';
// 유사 배열이므로 배열과 유사하세 인덱스를 사용해 각 문자 접근 가능
console.log(str[0]); // s
// 원시 값인 문자열은 객체처럼 동작한다.
console.log(str.length); // 6
console.log(str.toUpperCase); // string
// 문자열은 원시 값이므로 변경할 수 없다. 에러는 미발생
str[0] = 'S';
console.log(str); // string
변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달된다. 이를 값에 의한 전달이라 한다.
// 원시 값 80이 복사되어 전달
// 따라서 score의 값을 변경해도 복사된 값이기 때문에 영향이 없다
let score = 80;
let copy = score;
score = 100;
console.log(score); // 100
console.log(copy); // 80
// 값 80을 갖는 점에서는 동일하지만, 다른 메모리에 저장된 별개의 값
let tt = 80;
let dd = tt;
console.log(tt, dd); // 80 80
console.log(tt === dd); // true
✅ 엄밀히 따지면, 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달되기 때문에 변수와 같은 식별자는 값이 아니라 메모리 주소로 기억하고 있다.
✅ 결론은 두 변수의 원시 값은 서로 다른 메모리 공간에 저장되므로 재할당을 통해 값이 변경되어도 서로 간섭할 수 없다.
객체는 프로퍼티 개수가 정해져 있지 않으며, 동적으로 추가되고 삭제할 수 있다.
때문에 프로퍼티의 값에 제약이 없고, 원시 값과 같이 확보 할 메모리 공간의 크기를 사전에 정해 둘 수 없다.
객체(참조)는 변경 가능한 값이다. 객체를 할당한 변수가 기억한 메모리 공간에 접근하면 참조 값에 접근 가능하다. 참조 값은 생성된 객체가 저장된 메모리 공간의 주소 그 자체다
✅ 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다.
let person = {
name: 'lee';
}
// 값 갱신
person.name = 'kim';
// 프로퍼티 동적 생성
person.address = 'seoul';
const 0 = { x: { y: 1 } };
// 얕은 복사
const c1 = { ...o };
console.log(c1 === 0) // false
console.log(c1.x === 0.x) // true
// lodash의 cloneDeep을 사용한 깊은 복사
// npm으로 lodash 설치 후 node.js환경에서 실행
const _ = require('lodash');
// 깊은 복사
const c2 = _.cloneDeep(o);
console.log(c2 === 0) // false
console.log(c1.x === 0.x) // false
객체를 가르키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. 이를 참조에 의한 전달이라 함.