Deep Dive - 11.원시값과 객체의 비교

Jihyun-Jeon·2022년 5월 29일
1

Javascript - Deep Dive

목록 보기
24/26

< 요약 >

원시 타입객체 타입
변수에 할당하면?실제 값이 저장됨참조값이 저장됨
각 타입의 값원시값 : 변경 불가능한 값객체 타입의 값 : 변경 가능한 값
원시값을 갖는 변수를 다른 변수에 할당하면?원시값이 복사됨.참조값이 복사됨.

※ 사전지식
- 변수명(식별자) : 변수 값이 저장되는 ‘메모리 공간’을 지칭하기 위해 붙인 이름이고
- 변수의 값은 : 메모리에 저장된 ‘데이터 자체’이다.


🔶 원시타입

1️⃣ 원시값을 변수에 할당하면? - 값을 저장함.

let score = 80;
  • < 코드 생성과정 >
    1)새로운 메모리 주소에 공간을 만들고
    2) score식별자는 그 주소를 가르키게 된다.
    3)메모리 공간에 80이라는 “값”을 할당한다.

  • 식별자(score)는 “값(80)"이 아니라, 값이 담긴 “메모리 주소"를 기억하고 있는 것임.

2️⃣ 원시값은 변경 불가능 하다.(불변성)

  • 원시값은 불변성을 띈다. 때문에 재할당을 통해 값을 교체할 수 있음.

  • 메모리에 저장되있는 "원시값"은 변경할 수 없지만, 재할당을 통해 새로운 메모리 공간을 확보하고 그곳에 재할당한 값을 저장한 후, 변수 식별자가 참조하던 "메모리 공간의 주소가 변경"되어 재할당 되는 것임.
    (원시값이 변경 불가능한 값이기 때문에 변수가 참조하던 메모리 공간의 주소가 변경되는 것!)

  • 예제코드
var num;
num = 80;
num = 100;

  • 문자열과 불변성
    : 문자열은 원시값이므로 값을 변경할 수 없다.
    (변수에 새로운 문자열을 할당하는 재할당은 가능)
let str = "hello";
str[0] = "j";
console.log(str) // "hello" 

3️⃣ 값에 의한 전달

let score = 80;
let copy = score;

// [p1]
console.log(score); // 80
console.log(copy); // 80

score = 100; 

// [p2]
console.log(score); // 100
console.log(copy); // 80 !!

[p1] 원시값을 갖는 변수를 다른 변수에 할당하면? - “값”이 복사됨.

: copy변수에 원시값을 갖는 변수인 score을 할당하면, copy에는 score의 “원시값”이 복사되어 전달됨.

[p2]

: score변수와 copy변수는 같은 값(80)을 갖지만, 다른 메모리 공간에 저장된 별개의 값이다!
때문에 score값을 재할당해도 copy변수의 값에는 영향을 주지 않는 것임!

🔶 참조타입

1️⃣ reference type을 변수에 할당하면? - 참조값이 저장됨

let person = {name:"Lee"};

< 코드 생성과정 >
1) 메모리 주소(0x001)에 공간을 만들어지고
2) 변수 식별자는 그 메모리 주소(0x001)를 가르키게 된다.
3) 다른 메모리 공간(0x002)에 실제 객체값이 담긴다.
4) 메모리 공간(0x001)에 저장된 참조값이 이 실제 객체를 가르키게 된다.

< 객체값을 참조하는 과정 >

  • 변수 키워드가 기억하는 메모리 주소를 통해 메모리 공간(0x001)에 접근하면, 참조값에 접근할 수 있다.
  • 참조값은 실제 객체 값이 저장된 메모리 공간을 가리키는 주소이다.
  • 이렇게 참조값을 통해 실제 객체에 접근할 수 있는 것이다!

2️⃣ 참조값은 변경 가능하다.

원시값은 변경 불가능한 값이므로 재할당을 통해 새로운 메모리에 원시값을 새로 생성해야 했지만,
참조값은 변경 가능한 값이므로 기존 메모리에 있는 객체를 직접 수정할 수 있다.

let person = {name:"Lee"};

person.name = "Kim";
person.adress = "Seuol";

3️⃣ 참조에 의한 전달

let person = {name:"Lee"};
let copy = person; // 얕은 복사, person의 참조값을 복사한 것임.

원시타입은 원시”값”자체가 복사되어 전달되지만, 참조타입은 “참조값(reference)”가 복사되어 전달된다.
때문에 person과 copy는 메모리 주소는 다르지만, 동일한 참조값을 공유하고 있게 된다.
따라서 person과 copy 중 한쪽에서 객체를 수정하면 서로 영향을 받게 된다.

🔆 값이 같은 두 객체의 비교

let obj1 = {a : 1};
let obj2 = {a : 1};

console.log(obj1 === obj2); // false
console.log(obj1.a === obj2.a); // true
  • 두 객체는 내용은 같지만 다른 메모리에 저장된, 즉 "참조값이 다른 별개의 객체"다.
  • 그치만 객체 내용이 같아서 동일한 내용이 나오는 것이다.

얕은 복사, 깊은 복사

얕은 복사와 깊은 복사로 생성된 원본과 복사본은 참조 값이 다른 별개의 객체다.

하지만 중첩 객체를 복사하는 경우

  • 얕은 복사 : 한단계 까지만 복사하고, 중첩된 객체는 참조 값을 복사하여 원본과 사본이 값을 공유하게 된다.
  • 깊은 복사 : 중첩된 객체까지 모두 복사해서 원시 값처럼 완전한 복사본을 만든다.
const obj = {x:{y:1}};

// 얕은 복사
const c1 = {...obj}; // {y:1}객체는 원본과 사본이 같은 값을 공유하게 된다.

// 깊은 복사
const c2 = JSON.parse(JSON.stringify(obj));

0개의 댓글