자바스크립트에서 제공하는 데이터 타입은
크게 원시 타입(premitive type) 과 객체 타입(obejct/reperence type) 으로 구분 하는데, 둘 사이는 차이점이 존재한다.
원시 타입은
변경 불가능한 값으로 읽기 전용(read only) 값이다.
JavaScript에서 원시 값(primitive, 또는 원시 자료형)이란 객체가 아니면서 메서드도 가지지 않는 데이터입니다. 원시 값에는 7종류, string, number (en-US), bigint (en-US), boolean, undefined, symbol, 그리고 null이 존재합니다.
( 출처 : MDN )
// const 키워드를 사용 해 선언한 변수는 재할당이 금지된다. 상수는 재할당이 금지된 변수일 뿐이다.
const o = {};
// const 키워드를 사용해 선언한 변수에 할당한 원시 값(상수)은 변경할 수 없다.
// 하지만 const 키워드를 사용해 선언한 변수에 할당한 객체는 변경할 수 있다.
o.a = 1;
console.log(o); // {a: 1}
원시 값을 할당한 변수에 새로운 원시 값을 재할당 하면,
문자열은
유사 배열 객체로서 배열과 유사하게 각 문장에 접근 할 수 있으나,
변경 불가능 한 값 이기 때문에 일부 문자를 변경해도 반영되지 않는다.
원시 타입은 문자열은 읽기 전용 이기 때문이다.
원시 값을 저장하려면 먼저 확보해야 하는 메모리 공간의 크기를 결정해야 한다.
var str = 'string';
// 문자열은 유사 배열이므로 배열과 유사하게 인덱스를 사용해 각 문자에 접근할 수 있다.
// 하지만 문자열은 원시값이므로 변경할 수 없다. 이때 에러가 발생하지 않는다.
str[0] = 's';
console.log(str); // string
변수에 원시 값을 할당하면, 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달 된다.
var score = 90;
var copy = score;
console.log(score); // 90
console.log(copy); // 90
score = 100
console.log(score); // 100
console.log(copy); // 100
score 변수와 copy 변수는 숫자 값 100을 갖는다는 점에서는 동일하지만,
score 변수와 copy 변수의 값 100은 다른 메모리 공간에 저장된 별개의 값이다.
즉, 값에 의한 전달은 사실 값을 전달하는 것이 아니라 메모리 주소를 전달한다.
중요한 것은
변수에 원시 값을 갖는 변수를 할당하면, ( 위와 같이 )
변수 할당 시점 이든, 두 변수 중 어느 하나의 변수에 값을 재할당 하는 시점 이든
두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값 이 되어
어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없다.
따라서 메모리를 효율적으로 사용하기 위해,
그리고 객체를 복사해 생성하는 비용을 절약하여 성능을 향상시키기 위해
-> 객체는 변경 가능한 값으로 설계되어 있다.
객체(참조) 타입의 값은 변경 가능한 값 이다.
객체를 프로퍼티 값으로 갖는 객체인 경우
const o = { x: { y: 1 } };
// 얕은 복사
const c1 = { ...o }; // 스프레드 문법
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
const v = 1;
// "깊은 복사"라고 부르기도 한다.
const c1 = v;
console.log(c1 === v); // true
const o = { x: 1 };
// "얕은 복사"라고 부르기도 한다.
const c2 = o;
console.log(c2 === o); // true
얕은 복사와 깊은 복사로 생성한 객체는 원본과는 다른 객체다.
-> 원본과 복사본은 참조 값이 다른 별개의 객체다.
객체를 가리키는 변수(원본 person) 을 다른 변수(사본 copy)에 할당하면,
원본의 참조 값이 복사되어 전달 되는 것
var person = {
name: 'Lee'
};
// 참조값을 복사(얕은 복사)
var copy = person;
위의 코드에서 person과 copy 모두 동일한 객체를 가리키는데
이는 두 개의 식별자가 하나의 객체를 공유 한다는것을 의미한다.
값에 의한 전달 과 참조에 의한 전달 은