원시 타입(숫자, 문자열, boolean, null, undefined, symbol, object) 타입은 변경 불가능한 값이다. 한번 생성된 원시 값은 읽기전용(read only)이다.
변수와 헛갈리지 말자~!
변수 : 값을 교체할 수 있다.
상수 : 재할당이 금지된 변수
원시값이 변경이 불가능하기 때문에 변수가 참조하던 메모리 공간의 주소가 변경되는 식으로 변수의 내용이 변경된다.
문자열은 0개 이상의 문자로 이루어진 집합이다. 1개의 문자는 2바이트의 메모리에 저장된다. 문자열은 몇개의 문자로 이루어져있는지에 따라 사용하는 메모리 공간의 크기가 다른 특징을 가진다.
C언어는 char뿐 문자열을 지원하지 않지만 자바스크립트는 String 객체를 지원하는 특징이 있다.
문자열은 유사 배열로 처리된다.
let str1 = "Hello"
console.log(str[0]) //H
console.log(str.length) //5
하지만 원시값 이기 때문에
str[1] = "N" 이런건 불가능하다.
var score = 80;
var copy = score;
console. log(score); // 80
console. log(copy); / 80
score = 100;
console. log(score); / 100
console. log(copy); // 80
var copy = score; 여기에서 score은 값인 80으로 평가되어 var copy = 80; 과 동일한 작동이 이루어진다.
이처럼 변수에 원시 값을 갖는 변수를 할당하면 원시 값이 복사되어 변수에 할당된다.
둘다 80이지만 score변수와 copy변수가 가리키는 메모리 공간은 서로 다르다!
-> 사실 값의 의한 전달은 자바스크립트에 정의 되어 있지 않아 각 브라우저마다 구현의 방법 차이는 있음, "값에 의한 전달"은 사실 값을 전달하는 것이 아닌 메모리 주소를 전달하고, 전달받은 메모리의 주소를 통해 메모리 공간에 접근해 "값"을 참조한다.
결론 : 값의 의한 전달로 만들어진 두 변수는 가리키는 메모리 공간이 달라 어느 한쪽의 값의 변화와 상호 무관하다.
객체는 프로퍼티 개수가 정해져 잇지 않고, 동적으로 추가 삭제가 자유롭다. 따라서 객체는 원시값과 다르게 확보해야할 메모리 크기를 사전지정 불가능하다.
객체는 변경 가능한 값이다.
원시 값을 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하여 원시값에 접근할 수 있다.
원시 값을 할당한 변수는 원시 값 자체를 값으로 갖는다.
객체를 할당한 변수가 기억하는 메모리 공간에 접근하면 참조 값에 접근할 수 있다.
참조 값은 생선된 객체가 저장된 메모리 공간의 주소 그자체다
객체는 원시 값과는 다르게 여러개의 식별자가 하나의 객체를 공유할 수 있다.
앝은 복사 : 한 단계까지만 복사하는 것
깊은 복사 : 객체에 중첩되어 있는 객체까지 모두 복사하는 것
얕은 복사와 깊은 복사를 통해 생성된 객체는 모두 원본과 다른 객체다.
const o = { x: { y: 1 } };
1/ 얕은 복사
const c1 = { . . . o }; 1/ 35 장 스프레드 문법" 참고
console.log(c1 === o); / false
console.log(c1.x === 0.x); / true
/ / lodash의 cloneDeep 을 사용한 깊은 복사
1/"npm install todash" 로 Lodash 를 설치한 후, Node.js 환경에서 실행
const _ = require('lodash');
// 깊은 복사
const c2 = _.cloneDeep(o);
console. log(c2 = 0); / / false
console. log(c2.x = 0.x); / / false
var person = {
name: 'Lee'
};
// 참조 값을 복사(얕은 복사)
var copy = person ;
객체를 가리키는 변수가 다른 변수에 할당되면 원본의 참조 값이 복사되어 전달되는 것을 참조에 의한 전달이라고 한다.
다수의 식별자가 하나의 객체를 공유한다. 따라서 어느 한쪽의 식별자를 통해 객체를 변경하면 서로 영향을 주고 받는다.
값의 의한 전달
let original = 100;
let copy = original;
original = 120
console.log(original) //120
console.log(copy) //100
값의 의한 전달은 위와 같이 원시값일 때, 실제 값 자체를 비교하기 때문에 다른 변수에 복사하였을 때, 값만 같고 메모리 주소는 다르다. 따라서 어느 한 변수의 값을 변경하여도 서로 영향을 주지 않는다.
let original = {
name: 'Tony'
};
let copy = original;
console.log(original) //{name:"Tony"}
console.log(copy) //{name:"Tony"}
copy.name = "Kim"
console.log(original) //{name:"Kim"}
console.log(copy) //{name:"Kim"}
참조에 의한 전달은 위와 같이 객체일 때, 메모리 주소를 가리키기 때문에 다른 변수에 복사하였을 때, 가리키는 메모리 주소가 같다. 따라서 어느 한 변수의 값을 변경하면 서로 영향을 받는다.