[JS DeepDive] 원시 값과 객체의 비교

채연·2024년 5월 23일
0

목록 보기
23/26

데이터 타입

데이터 타입은 크게 원시타입, 객체 타입으로 나눌 수 있다.

위의 표는 이번 포스트에서 나올 이야기를 요약한 사진이다.
다 이해가 된다면 이 포스트는 읽을 필요가 없을 것이다!

원시 값

원시 타입의 값(즉, 원시값)은 변경 불가능한 값이다.

원시 값을 이야기하기에 앞서 알아야 할 개념들이 있는데, 변수와 값이다.

변수와 값

변수 : 하나의 값을 저장하기 위해 확보한 메모리 공간
: 변수에 저장된 데이터로 표현식이 평가되어 생성된 공간

a = 3 이라는 코드가 있다고 가정하자.

3이라는 값을 저장하기 위해 메모리 공간이 필요한데
변수란, 그 메모리 공간 혹은 메모리 공간을 식별하기 위해 붙인 이름을 말한다.

  • 위의 예시에선 a(밑의 사진에선 0x000000F2)가 될 것이다.

값은 말 그대로 변수에 저장된 데이터이다.

  • 위의 예시에선 3이 될 것이다.

실제 메모리 저장 예시

0x000000f2라는 곳에 메모리를 확보하여 3이라는 값이 저장된다.

원시 값의 재할당

"원시 값은 변경 불가능하다" 라는 말은, 값을 변경할 수 없다는 뜻이지 변수의 값을 변경할 수 없다는 뜻이 아니다.

위의 예시를 이용하여 이해해보자

var = a = 3

a = 3으로 값을 선언해주었다.

var a = 3
a = 4

그리고 다시 4로 변경을 해준다.
어떻게 하면 메모리에서 이 값을 변경시켜줄 수 있을까?

-> 위의 사진과 같이 변화를 시킨다면 "원시 값은 변경 불가능하다"라는 말에 위배가 된다.

그럼 도대체 어떻게 할 수 있지..?

결과를 말하자면,
새로운 메모리 공간을 확보하고 재할당한 원시 값을 저장한 후, 변수는 새롭게 재할당한 원시 값을 가리킨다.

  1. a = 4와 같이 재할당이 일어난다면
  2. 새로운 메모리 공간을 할당 (위의 사진에서는 0x00001332)하게 되고
  3. 그 메모리 공간에 원시 값 (위의 사진에서는 4)이 저장된 후
  4. 변수가 참조하던 메모리 공간의 주소가 바뀐다. (위의 사진에서는 파란색 a가 이동)

문자열과 불변성

자바스크립트에선 문자열 타입을 제공하는데, 이는 원시타입으로 분류된다.
따라서 변경이 불가능하다.

var str = 'Hello'
str = 'world'

위의 내용과 비교하면 위의 코드는 어떻게 메모리에 저장될까?

똑같이 원시타입이므로 위와 같이 메모리에 저장된다.


유사 배열 객체

문자열은 배열과 유사하게 문자에 접근할 수 있다는 것을 알고 있을 것이다.

var str = 'string'
console.log(str[0]); // s

여기에서 주의해야 할 점은, 문자열은 원시 값이므로 변경할 수 없다는 점이다.

var str = 'string'
str[0] = 'S'

console.log(str) // string

위에서 계속 설명했던 것과 같이 변수의 재할당을 통해 변수에 할당된 값을 변경할 수는 있지만,
바로 위의 코드와 같이 값을 변경하는 것은 불가능하다.

위의 코드를 동작하게 하고 싶다면

var str = 'string'
str = 'String'

console.log(str) // String

이와 같이 코드를 짤 수 있을 것이다.
이는 기존 문자열을 변경하는 것이 아니라 새로운 문자열을 새롭게 할당하는 것이기 때문이다!

값에 의한 전달

var  score = 80;
var copy = score;

score = 100;

console.log(score) // 100
console.log(copy) // ?

이 코드에서 copy는 무슨 값을 가질까?

  1. score의 값을 변경했으므로 score만 값이 변경되어 copy는 80의 값을 가질 것이다.

  1. copy와 score가 같은 메모리 공간을 보고 있을 것이므로 copy는 100의 값을 가질 것이다.

이 두 개의 의견으로 나뉠 수 있다.

자바스크립트에선 어떻게 동작할까??
그림과 함께 알아보자!

  1. score에 80의 값을 선언한다.

  1. copy에 score 값을 넣어준다.
    -> 이때, copy를 위한 메모리 공간이 할당되고 그곳에 score의 값이 복사되어 들어간다.

  1. score 값을 변경한다.
    -> score의 변경된 값을 넣을 메모리 공간이 할당되고 그곳에 바뀐 score의 값이 들어간다.

이 상황에서 console을 찍었을 때 copy는 80, score는 100이 나오게 되는 것이다!

정답은 1번이었다 :D

copy에 score의 값을 넣어주는 과정에서 메모리의 주소를 주는 것이 아닌, score의 값을 복사한다해서 이것을 값에 의한 전달이라고 부른다.

+) 메모리의 주소를 준다고 했을 경우에는 2번의 결과가 나왔을 것이다.

변수가 메모리의 공간을 본다하면 위의 사진과 같은 결과가 나오기 때문이다.


객체

원시 값에 대해 알아봤으니 이번엔 객체에 대해서 알아보자!

객체는 변경 가능한 값이다.
위의 이야기를 완벽히 이해했다면 딱 드는 생각이 있을 것이다.

값을 변경할 때 재할당해주지 않아도 되겠다! 즉, 새로운 메모리 공간을 만들지 않고 그냥 값이 변경되어도 되겠다!!

정답이다.

객체는 복합적인 자료구조이므로 경우에따라 매우 크기가 큰 값을 저장해야 할 수도 있다.
이때마다 메모리 공간을 차지하는 것은 매우 비효율적이게 된다.

따라서, 객체는 변경가능한 값으로 설계되어 있다.

변경가능한 값

변수에 객체를 할당하게 된다면 어떤 일이 일어날까?

변수는 참조 값으로 메모리 공간에 접근할 수 있다.
참조 값은 생성된 객체가 저장된 메모리 공간의 주소이다.

그림으로 알아보자!

var person : { name : 'Lee' }

상황 : person에 { name : 'Lee' } 라는 객체를 할당했다.

  1. 이것을 저장할 메모리가 하나 생성될 것이고, 거기에 객체가 담기게 된다.

  1. 메모리 공간이 하나 더 생성되고, 값에는 객체가 담긴 메모리의 주소가 입력된다.

  1. 변수는 2번의 메모리 주소를 향한다.

  1. 결과

Person 변수는 객체 { name : 'Lee' } 를 참조하고 있다고 말할 수 있다.

재할당

원시 값은 변경 불가능한 값이므로 변수의 값을 변경하려면 재할당 외에는 방법이 존재하지 않았다.
하지만 객체는 재할당 없이 객체를 직접 변경할 수 있다.

var person = { name : 'Lee' }

person.name = 'Kim'
person.address = 'Seoul'

console.log(person) // { name : 'Kim', address: 'Seoul' }

원시 값이었으면 재할당을 통해서 새로운 메모리 공간을 할당하였지만, 객체는 기존 메모리 공간에 그대로 값만 변경된 모습이다.

참조에 의한 전달

원시 값과 다르게 객체는 여러 개의 식별자가 하나의 객체를 공유할 수 있다.

복사

var person = { name : 'Lee' }

var copy = person

객체는 값을 복사할 때 참조 값을 복사하게 된다.
그렇게 된다면 다음과 같은 값을 초래하게 될 것이다.

  1. { name : 'Lee' }가 담겨있는 메모리 공간이 할당되고
  2. 그것을 참조하는 메모리 공간을 person 변수가 바라본다.
  3. copy가 복사될 때 참조 값을 복사하게 되므로 copy 변수도 person 변수와 같이 같은 메모리 공간을 바라보게 된다.

같은 메모리 공간을 바라보게 되면 어떻게 될까?

var person = { name : 'Lee' }
var copy = person

person.name = 'Kim'
copy.address = 'Seoul'

console.log(person) // { name : 'Kim', address: 'Seoul' }
console.log(copy) // { name : 'Kim', address: 'Seoul' }

같은 메모리 공간을 보고 있으므로 서로의 값을 변경하면 서로에게 영향을 미칠 것이다!

마무리

이 포스팅을 보고 이 표가 이해가 되었으면 좋겠당 🫶

profile
Hello Velog

0개의 댓글