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

이주희·2022년 11월 7일
0

JavaScript

목록 보기
44/49

JS가 제공하는 7가지 데이터 타입은 크게 원시 타입 객체 타입으로 구분된다.
원시 타입과 객체의 차이점 세가지를 알아보자!

1. 값 변경 가능 여부

1-1. 원시 값 : 변경 불가능(불변성)

  • 원시 타입(primitive type)의 값은 변경 불가능한 값(immutable value)이다.

    💡 변수 값을 변경할 수 없다는 것이 아니라, 원시 값 자체를 변경할 수 없다는 것이다! 헷갈 ㄴㄴ
    변수는 재할당을 통해 변수 값을 변경(교체) 할 수 있다. 그래서 이름도 변수..

  • 이러한 원시 값의 특성은 데이터의 신뢰성을 보장한다.

  • 원시 값을 할당한 변수는 재할당 이외에 변수 값을 변경할 수 있는 방법이 없다.

  • 원시 값을 할당한 변수에 새로운 원시 값을 재할당하면 변수가 참조하던 메모리 공간의 주소가 바뀐다.

    재할당

    • 메모리 공간에 저장되어 있는 재할당 이전의 원시 값을 변경하는 것 아님❌
    • 새로운 메모리 공간을 확보하고 재할당한 원시 값을 저장한 후, 변수는 새롭게 재할당한 원시 값을 가리킨다.

문자열

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

  • 1개의 문자는 2byte의 메모리 공간에 저장된다. 문자열은 몇 개의 문자로 이뤄졌느냐에 따라 필요한 메모리 공간의 크기가 결정된다.
    (숫자 값은 1도, 1000000도 동일한 8byte)

  • 문자열은 유사 배열 객체이면서 이터러블이므로 배열과 유사하게 각 문자에 접근할 수 있다.

  • 문자열은 변경 불가능한 원시 값이므로 변경은 불가능하다.

    유사 배열 객체

    array like object
    배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고, length 프로퍼티를 갖는 객체를 말한다.
    원시 값을 객체처럼 사용하면 원시값을 감싸는 래퍼 객체로 자동 변환된다.


1-2. 객체 :: 변경 가능

  • 변경 가능한 값(mutable value)이다.

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

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

    🧐 Why? 왜 객체는 변경 가능하게 만들었을까?

    메모리의 효율적 소비가 어렵고 성능이 나빠지기 때문이다!
    객체를 변경할 때마다 원시 값처럼 이전 값을 복사해서 새롭게 생성한다면 명확하고 신뢰성이 확보되겠지만
    객체는 크기가 매우 클 수도 있고, 원시 값처럼 크기가 일정하지 않으며
    프로퍼티 값이 객체일 수도 있어서 복사해서 생성하는 비용이 많이 든다.
    따라서 메모리를 효율적으로 사용하기 위해, 그리고 객체를 복사해 생성하는 비용을 절약하여 성능을 향상시키기 위해 객체는 변경 가능한 값으로 설계되어 있다.


2. 변수에 저장되는 값

2-1. 원시 값: 원시 값

  • 원시 값을 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 원시 값에 접근할 수 있다.

  • 표현: '변수는 O값을 갖는다.', '변수의 값은 O다.'


2-2. 객체 : 참조 값

reference value

  • 객체를 할당한 변수가 기억하는 메모리 주소를 통해 메모리 공간에 접근하면 참조 값에 접근할 수 있다.

  • 참조 값은 생성된 객체가 실제로 저장된 메모리 공간의 주소로, 이 참조 값을 통해 객체에 접근할 수 있다.

  • 표현: '변수는 객체를 참조하고 있다.', '변수는 객체를 가리키고 있다.'


2-3. 얕은 복사 shallow copy vs 깊은 복사 deep copy

  • 객체를 프로퍼티 값으로 갖는 객체의 경우
    얕은 복사는 한 단계까지만 복사하는 것을 말하고,
    깊은 복사는 객체에 중첩되어 있는 객체까지 모두 복사하는 것을 말한다.

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

  • 얕은 복사는 객체에 중첩되어 있는 객체의 경우 참조 값을 복사하고,
    깊은 복사는 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사본을 만든다는 차이가 있다.


3. 값에 의한 전달 vs 참조에 의한 전달

3-1. 원시 값 : 원시값이 복사되어 전달

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

  • 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달되는 것이다.
    (변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하고 있기 때문!!)

변수 할당 시 동작 방식

ECMAScript 사양에 명확하게 정의되어 있지 않아 JS 엔진을 구현하는 제조사에 따라 실제 내부 동작 방식은 차이가 있을 수 있다.

var x = 10;
var copy = x;

위 예제는 아래의 두 가지 평가 방식이 가능하다.

1) 새로운 10을 생성해서 메모리 주소를 전달하는 방식
👉🏻 할당 시점에 두 변수가 기억하는 메모리 주소가 다르다.

2) x의 변수값 10의 메모리 주소를 그대로 전달하는 방식
👉🏻 할당 시점에 두 변수가 기억하는 메모리 주소가 같다.


3-2. 객체 : 참조값이 복사되어 전달

  • 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.

  • 메모리 주소는 다르지만 동일한 참조 값을 갖는다. (동일한 객체를 가리킨다.)

  • 두 개의 식별자가 하나의 객체를 공유해, 프로퍼티가 변경되면 서로 영향을 주고받는다.

profile
🍓e-juhee.tistory.com 👈🏻 이사중

0개의 댓글