모던 자바스크립트 Deep Dive_원시 값과 객체의 비교

모던 자바스크립트 Deep Dive_원시 값과 객체의 비교

·

4 min read

11_원시 값과 객체의 비교

자바스크립트에서 제공하는 데이터 타입은
크게 원시 타입(premitive type)객체 타입(obejct/reperence type) 으로 구분 하는데,둘 사이는 차이점이 존재한다.

  1. 원시 타입 값은 변경 불가능 한 값 이고, 객체(참조) 타입 값은 변경 가능한 값 이다.

  2. 원시 타입 값을 변수에 할당하면 변수(확보된 메모리 공간) 에는 실제 값이 저장 객체(참조) 타입 값은 변수(확보된 메모리 공간)에는 참조 값이 저장

  3. 원시 타입 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달
    객체 타입 값을 갖는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달

11.1 원시 타입

11.1.1 변경 불가능한 값

원시 타입은 변경 불가능한 값으로 읽기 전용(read only) 값이다.

원시 값 자체를 변경 불가능하다는 것이지, 변수 값을 변경 할 수 없다는 것이 아님을 유의!

carbon (89)

원시 값을 할당한 변수에 새로운 원시 값을 재할당 하면,

  1. 메모리 공간에 저장되어 있는 재할당 이전의 원시 값을 변경하는 것이 아니라

  2. 새로운 메모리 공간을 확보 하고 재할당한 원시 값을 저장한 후 ➡️ 메모리 공간의 주소가 변경된 이유는, 변수에 할당된 원시 값이 변경 불가능한 값이기 때문

  3. 변수는 새롭게 재할당한 원시 값을 가리킨다.

이러한 특성을 불변성이라고 한다. 불변성을 갖는 원시 값을 할당한 변수는 재할당 이외에 값을 변경 할 수 있는 방법이 없다.

11.1.2 문자열과 불변성

문자열은 유사 배열 객체로서 배열과 유사하게 각 문장에 접근 할 수 있으나, 변경 불가능 한 값이기 때문에 일부 문자를 변경해도 반영되지 않는다. 원시 타입은 문자열은 읽기 전용이기 때문이다.

원시 값을 저장하려면 먼저 확보해야 하는 메모리 공간의 크기를 결정해야 한다.

  • 이를 위해 원시 타입별로 메모리 공간의 크기가 미리 정해져 있다.

  • ECMAScript 에 따르면, 문자열 타입(2바이트) 와 숫자 타입(8바이트)

그외 원시 타입은 크기를 명확히 규정하고 있지 않다.

carbon (90)

11.1.3 값에 의한 전달

변수에 원시 값을 할당하면, 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달 된다.

carbon (91)

score 변수와 copy 변수는 숫자 값 100을 갖는다는 점에서는 동일하지만,
score 변수와 copy 변수의 값 100은 다른 메모리 공간에 저장된 별개의 값이다.

중요한 것은

➡️ 변수에 원시 값을 갖는 변수를 할당하면, ( 위와 같이 ) ➡️ 변수 할당 시점 이든, 두 변수 중 어느 하나의 변수에 값을 재할당 하는 시점 이든 ➡️ 두 변수의 원시 값은 서로 다른 메모리 공간에 저장된 별개의 값이 되어 ➡️ 어느 한쪽에서 재할당을 통해 값을 변경하더라도 서로 간섭할 수 없다.

11.2 객체 타입

프로퍼티의 개수가 정해져 있지 않아 동적으로 추가되고 삭제할 수 있고 프로퍼티의 값에도 제약이 없다.

원시 값과 같이 확보해야 할 메모리 공간의 크기를 사전에 정해 둘 수 없고
복합적인 자료구조라서 ,원시 값과는 다른 방식으로 동작하도록 설계되어 있다.

이유는 ❓

객체를 변경할 때 마다 복사해서 생성 후 변경하면 비용이 많이 든다.

➡️ 원시 값처럼 이전 값을 복사해서 새롭개 생성한다면 명확하고 신뢰성이 확보되겠지만 ➡️ 객체는 크기가 매우 클 수도 있고 원시 값처럼 크기가 일정하지도 않으며 ➡️ 프로퍼티 값이 객체일 수도 있다.

따라서 메모리를 효율적으로 사용하기 위해, 그리고 객체를 복사해 생성하는 비용을 절약하여 성능을 향상시키기 위해 ➡️ 객체는 변경 가능한 값으로 설계되어 있다.

11.2.1 변경 가능한 값

객체(참조) 타입의 값은 변경 가능한 값 이다.

  • 객체를 할당한 변수는 재할당 없이 객체를 직접 변경 할 수 있다.

  • 즉, 재할당 없이 프로퍼티를 동적으로 추가 할 수 있고

  • 값을 갱신 할 수 있으며, 자체를 삭제 할 수 있다.

11.2.2 얕은 복사와 깊은 복사

객체를 프로퍼티 값으로 갖는 객체인 경우

  • 얕은 복사한 단계 까지만 복사하는 것을 말하고 ➡️ 참조 값을 복사

  • 깊은 복사객체에 중첩되어 있는 객체 까지 복사하는 것을 말한다.
    ➡️ 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사본을 만드는 복사

carbon (92)

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

11.2.3 참조에 의한 전달

객체를 가리키는 변수(원본 person) 을 다른 변수(사본 copy)에 할당하면, 원본의 참조 값이 복사되어 전달되는 것

carbon (93)

위의 코드에서 person과 copy 모두 동일한 객체를 가리키는데
이는 두 개의 식별자가 하나의 객체를 공유 한다는것을 의미한다.


정리

원시 타입과 객체 타입의 차이

원시타입과 가장 큰 차이점은 변수의 크기가 동적으로 변한다는 것이다.

이러한 특징 때문에 객체의 데이터 자체는 별도의 메모리 공간(heap)에 저장되며, 변수에 할당 시 데이터에 대한 주소 ( 힙(Heap) 메모리의 주소값)가 저장되기 때문에 자바스크립트 엔진이 변수가 가지고 있는 메모리 주소를 이용해서 변수의 값에 접근하게 되는것이다.

값에 의한 전달참조에 의한 전달

식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서 동일하지만, 식별자가 기억하는 메모리 공간(변수)에 저장되어 있는 값이 원시 값이냐 참조 값이냐에 차이가 있다.