ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2021_12_17 Deep_Dive 11장 원시 값과 객체의 비교
    IT/js 2021. 12. 18. 01:36

     

    정리

    데이터 타입은 원시타입과 객체 타입이 있다!

    더보기

    원시 타입의 특징

     - 원시 타입은 변경 불가능한 값

     - 원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다

     - 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달

     

    객체 타입의 특징

     - 객체 타입의 값은 변경이 가능하다

     - 객체를 변수에 할당하면 변수에는 참조값이 저장된다 (주소)

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

     

    1. 원시 값


    1.1 변경 불가능한 값

    원시 타입의 값, 즉 원시 값은 변경 불가능한 값이다. 다시 말해 한번 생성된 원시 값은 읽기 전용으로 값으로서 변경할 수 없다.

    값을 변경할 수 없다는게 뭔지 구체적으로 생각해보면

    변수와 값은 구분해서 생각해야한다.

     

    변수는 하나의 값을 저장하기 위해 확보한 메모리 공간 자체 또는 그 메모리 공간을 식별하기 위해 붙인 이름이고

    값은 변수에 저장된 데이터로서 표현식이 평가되어 생성된 결과를 말한다.

    변경 불가능한 것은 변수가 아니라 값에 대한 진술이다.

    즉, 원시 값은 변경 불가능하다 라는 말은 원시 값 자체를 변경할 수 없다는 것이지 변수 값을 변경할 수 없다는 건 아니다.

     

    원시 값을 변경 못한다는 것(o)

    변수 값을 변경 못한다는 것(x) -> 변수는 언제든 재할당을 통해 값을 변경할 수 있다(교체)

     

    변수의 상대 개념인 상수는 재할당이 금지된 변수를 말한다

    상수도 값을 저장하기 위한 메모리 공간이 필요하므로 변수라고 할 수 있다.

    단, 변수는 언제든 재할당을 통해 변수 값을 변경(교체)할 수 있지만 상수는 단 한번만 할당이 허용되므로 변수 값을 변경할 수없다.

    상수와 변경 불가능한 값을 동일 시 하는것은 곤란한다.

    -> 상수로 선언된 변수 <- 이 변수는 변경이 불가능한데 

    -> 변수에 할당, 재할당된 것은 변경이 가능하다

     

    const o = {}; // {} 는 변경할 수 없다
    
    o.a = 1; // 변수에 할당한 객체는 변경할 수 있다
    console.log(o); // {a:1}

     

    원시 값은 변경 불가능한 값, 즉 읽기 전용 값이다. 원시 값은 어떤 일이 있어도 불변

    원시값의 특성은 데이터의 신뢰성을 보장

    원시값은 변경하는게 아니라 메모리가 새로 할당되고 변경되는 것일뿐이다.

    이러한 특성을 불변성이라 한다.

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

    만약 재할당 말고 다른 방법이 있으면.. 그방법 외에도 다른방법이 있을것이다.

    이는 상태변경을 추적하기 어렵게한다.

     

    1.2. 문자열과 불변성

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

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

    문자열 2바이트, 숫자 8바이트 이외 원시 타입은 크기를 명확히 구정하지 않음

    원시 값인 문자열은 다른 원시 값과 비교할 때 독특한 특징이 있다.

    문자열은 0개 이상의 문자로 이뤄진 집합

    1개의 문자는 2바이트 메모리 공간에 저장

    따라서 문자열은 몇개의 문자로 이뤄졌냐에 따라 메모리 크기가 결정

    숫자 값은 1도 1000000도 동일한 8바이트

     

    -> 원시값 저장하려면 메모리 크기 미리 정해놔야함

    -> 문자열은 글자당 2바이트

    -> 숫자는 8바이트씩  ( 1을 넣어도 00000001 이렇게 잡힘 )

     

    문자열은 원시타입, 변경 불가, 생성된 이후에 변경할 수 없음

    var txt = 'Hello';
    txt = 'World';

    'Hello' 가 사라지는게 아닌 World 문자열이 새로 생성되고

    txt가 그걸 새롭게 가르키는 것 일뿐

    원시값은 재할당하는 것만이 변경가능한데 txt[0] = 'Z' ; 이런식으로 편집이 불가능하다

    그래서 신뢰성이 높다

     

    1.3 값에 의한 전달

    var score = 80;
    var copy = score;
    
    console.log(score); // 80
    console.log(copy); // 80
    
    score = 100;
    console.log(score); // 100
    console.log(copy); // 80

    변수에 별수를 할당했을때는 값에 의한 전달

    즉슨 copy는 80이라는 새로운 메모리 주소를 가진 데이터를 넘겨받는것

     

    파이썬에서는 같은 값 같은 주소를 보고있다가 변수 값이 변경될때 주소가 새로 바뀐다.

    이 책에서 타 언어에서 사용하는 값에 의한 전달, 참조에 의한 전달이라는 용어를 사용하지만

    공유에 의한 전달이라고 표현하는 경우도 있다

    참고로 "값에 의한 전달"이라는 용어는 js 위한 용어가 아니므로 사실 오해가 있을 수 있음

     

    엄격하게 표현하면 변수에는 값이 전달되는것이 아니라 메모리 주소가 전달되기 때문이다. 이는 변수와 같은 식별자는 값이 아니라 메모리 주소를 기억하고있기 때문이다.

     

    중요한 것은 변수에 원시 값을 갖는 변수를 할당하면 변수 할당 시점이든, 두 변수 중 어느 하나의 변수에 값을 재할당하는 시점이든 결국 두 변수의 원시 값은 서로 다른 메모리 공간에 별개의 값이 저장 되어 어느 한쪽에서 재할당을 통해 변경하더라도 서로 간섭할 수 없다는 것

     

    2.객체


      - 객체는 프로퍼티의 개수가 정해져 있지 않으며 동적으로 추가되고 삭제 가능

      - 프로퍼티 값에도 제약이 없다

      - 따라서 객체는 원시 값과 같이 확보해야할 메모리 공간의 크기를 사전에 정해 둘 수 없다.

     

    2.1. 변경 가능한 값

    객체 타입의 값은 변경 가능한 값이다.

    var person = {
    	name: 'Lee'
    };

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

    하지만 객체를 할당한 변수가 기억하는 메모리 공간에 접근하면 참조 값(reference value)에 접근할 수있다.

    참조 값은 생성된 객체가 저장된 메모리 공간의 주소 그 자체다.

     

    하나의 메모리 주소에 name:'Lee', age:'20' 이런거를 다 담고 있다

    즉 person 이란 변수에 안에 들어있는 주소가 들어있으므로 참조라고 한다.\

    따라서 객체를 할당한 변수는 재할당 없이 객체를 변경할 수 있다.

     

    객체를 생성하고 관리하는 방식은 매우 복잡하고 비용이 많이 드는 일

    객체를 변경할때마다 원시값처럼 이전 값을 복사해서 새롭게 생성하면 신뢰성이 확보 되겠지만

    비용이 크고 성능이 나빠진다.

    그래서 메모리 효율을 위해 객체는 수정, 삭제 등이 가능한 것

    단, 여러개의 식별자가 하나의 객체를 공유할 수 있음

     

    얕은 복사, 깊은 복사

    객체를 프로퍼티 값으로 갖는 객체의 경우 얕은 복사는 한 단계까지만 복사하는 것

    깊은 복사는 객체에 중첩되어 있는 객체까지 모두 복사하는 것을 말한다.

     

    얕은 복사와 깊은 복사로 생성된 객체는 원본과 다른 객체.

    원본과 복사본은 참조 값이 다른 별개의 객체.

    얕은 복사는 객체에 중첩되어 있는 객체의 경우 참조 값을 복사하고

    깊은 복사는 객체에 중첩되어 있는 개체까지 모두 복사해서 원시 값처럼 완전한 복사 법을 만든다는 차이가있다

     

    원시값 복사하는 것 (원시 값은 메모리를 아예 새로 잡으니깐) = 깊은 복사

    객체 할당한 변수를 다른 변수에 할당하는것을 얕은 복사라고 부르는 경우가 있다 (참조값만 복사)

     

    2.2. 참조에 의한 전달

    여러개의 식별자가 하나의 객체를 공유할 수 있음 이로인해 부작용 발생 할 수있다.

    객체를 변경하면 참조 받는 애 둘다 변경이 되어버린다.

    어느 한쪽에서라도 바꾸면.. 서로 영향을 준다.

     

    var person ={
    	name = 'Lee'
    };
    
    var copy = person;
    
    console.log(copy === person); // true
    
    copy.name = 'Kim';
    person.adress = 'Seoul;
    
    console.log(person);  // {name: "Kim", adress: "Seoul"};
    console.log(copy); 	// {name: "Kim", adress: "Seoul"};

     

    값이든 참조든 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면은 같다.

    원시값이냐 참조값이냐의 차이 그래서 js에선 값에 의한 전달만 있다고 말할 수 잇음

    참조에 의한 전달을 언급해도 되긴한데 다른 언어랑은 차이있으니 주의하기 바람

     

Designed by Tistory.