뮁이의 개발새발

[코어 자바스크립트] Chapter 1. 데이터 타입 본문

Front-end/Javascript

[코어 자바스크립트] Chapter 1. 데이터 타입

뮁뮁이 2024. 4. 8. 12:39

Chapter 1. 데이터 타입

  1. 데이터 타입의 종류
    1. 기본형 vs 참조형
      1. 기본형
        1. 값이 담긴 주솟값을 바로 복제
        2. 불변성을 가짐
      2. 참조형
        1. 값이 담긴 주솟값들로 이루어진 묶음을 가리키는 주솟값을 복제함.
  2. 데이터 타입에 관한 배경지식
    1. 메모리의 낭비를 최소화하기 위해, bit와 byte라는 데이터의 단위를 생성함.
    2. 그러나, 메모리 용량이 커진 현상황에서 자바스크립트가 등장.
    3. 이에 대한 결과로, 숫자는 정수/부동소수형의 구분 없이 8바이트를 확보하게 됨.
      1. 형변환 불필요
    4. 식별자란?
      1. 어떤 데이터를 식별하는 데 사용하는 이름, 즉 변수명
  3. 변수 선언
    • 변할 수 있는 데이터를 만든다. 이 데이터의 식별자는 a로 한다.
    1. 결국, 변수는 변경 가능한 데이터가 담길 수 있는 공간 또는 그릇
    2. 변수를 선언하는 순간, 해당 변수의 집주소(식별자)가 생김
      var a;
      a = 'abc';
      
      var a = 'abc';
    3. 3-2. 하단 두 변수 선언 방식의 차이는?
    4. 변수를 선언하는 시점에서, 해당 식별자에 데이터 값이 저장되지는 않음.
    5. ‘변수 영역’, ‘데이터’ 영역이 별도로 존재
      1. 참고 이미지
    6. 변수 영역 : a의 집주소에 a의 집이라는 정보와, a의 진짜 데이터 정보가 어디에 있는지 데이터영역쪽 집주소를 가지고 있음.
    7. 위 처럼 관리하는 이유
      1. 데이터의 변환을 자유롭게 할 수 있게 함과 동시에 메모리를 더욱 효율적으로 관리하기 위함
      2. 원래 집주소에 정보를 넣게되면, 데이터에 대한 크기 조절이 자유롭지 못함
    8. 만약 기존 변수에 변환을 가한다면?
      1. 기존의 ‘데이터’ 영역의 정보를 대체하는 것이 아닌, 신규 ‘데이터’ 공간에 정보를 저장하게 됨
      2. 이는 중복된 데이터에 대한 처리 효율을 높이기 위함!
  4. var a;
  5. 기본형 데이터와 참조형 데이터
    1. 불변값 ≠ 상수
    2. 변수와 상수를 구분 짓는 변경 가능성의 대상은 변수 영역 메모리이다.
    3. ‘데이터’ 영역쪽에 이미 데이터가 존재해버리는 순간, 해당 데이터는 새로 생성되지 않고 재활용됨. 데이터 영역의 집주소는 그대로. ⇒ 불변값의 성질
    4. 4-2. 기본형 데이터와 참조형 데이터의 차이?
    • 참조형 데이터는 ‘객체의 변수(프로퍼티) 영역’이 별도로 존재한다는 점.
    • ‘데이터 영역’ 내에도, 주소에 대한 정보가 있음. 해당 주소에 가면 “객체의 변수 영역”(또 다른 데이터 영역이라고 볼 수 있음) 의 주소가 존재.
    • 이미 데이터 영역에 작성된 내역 자체가 주소지를 의미하고 있기 때문에(비록 그것이 객체의 “변수 영역” 일지라도..) 해당 값은 변경이 안됨. ⇒ 해당 측면에서는 참조형 데이터가 불변하지 않다 라고 볼수 있음
    • 만약 재할당 명령을 내린다면?
      • 데이터 영역에 있는 주소값을 통해 ‘변수’ 영역을 아무도 조회하지 않는다면?
      • ⇒ Garbage collector(GC)의 수거 대상이 됨.
        5. 4-3. 변수 복사 비교
        - 기본형 데이터는 변수 영역 → 데이터 영역에 가서 주소지만 끌어오면 되니, 복사할때 새로운 주소값을 호출하기 되어 값이 변경될 수 있다고 판단됨.
        - 그러나 참조형 데이터의 경우, “객체의 변수” 영역에 한번 더 거쳐오기 때문에, “객체의 변수” 영역의 값이 변할지언정, 기존의 “변수” 영역에 있는 집주소 값은 변경되지 않음. (실 데이터 정보는 객체 변수 영역에 존재하니까~)
        - 변수를 복사하는 과정 자체는 기본형/참조형 모두 같은 주소를 바라보게 되는점에서는 동일함.
        - 따라서, 기본형 데이터는 복사 해도 주소지가 다르고, 참조형 데이터는 복사해도 주소지는 동일
            - a ≠= b / obj1 === obj2
        - 그러나 참조형 데이터도 완전히 다른 참조형 데이터 “자체”를 변경할 경우에는 주소지가 변경됨!
            - 따라서, 참조형 데이터가 ‘가변값’이라고 설명할 때는 내부의 프로퍼티를 변경할때만 성립함. (obj.a 같은 건들)
  1. 불변 객체
    1. 불변 객체를 만드는 간단한 방법
      1. 참조형 데이터의 ‘가변’은 데이터 자체가 아닌 내부 프로퍼티를 변경할때만 성립
      2. 데이터 자체를 변경하고자 하면(새로운 데이터를 할당) 기존 데이터는 변하지 않음.
        1. 내부 프로퍼티를 변경할 필요가 있을 때마다 매번 새로운 객체를 만들어 재할당한다면 불변성을 확보할 수 있음.
    • 예제 코드
      • user1과 user2는 같은 주소지를 가지고 있으며, 변할수있는 객체타입이기 때문에 이러한 결과를 초래
    • var user1 = { name: 'Lee', address: { city: 'Seoul' } }; var user2 = user1; // 변수 user2는 객체 타입이다. user2.name = 'Kim'; console.log(user1.name); // Kim console.log(user2.name); // Kim
    • 이런 경우 해야할 것
      • 객체를 불변성으로 만들기
      • 객체의 변경이 필요한 경우, 깊은 복사를 하기
  • 얕은 복사 vs 깊은 복사?
    • 얕은 복사 예시
    • var copyObject = function (target) { var result = {}; for (var prop in target) { result[prop] = target[prop]; } return result; };
    • 위 방법을 통해 기존의 객체를 변경하지 않고 새 객체를 생성하여 복사해올 수 있음. (얕은 복사)
    • 단점
      • 모두가 해당 함수를 통해 객체를 사용한다는 가정하에 불변성 유지가 가능
      • 그렇기 때문에 불안함이 존재. 시스템적으로 제약이 필요함 (ex : immutable.js, baobab.js)
      • 원본이 변하면 사본도 바뀜. 사본을 바꾸면 원본도 변경됨.
      • 바로 아래 단계의 값만 복사하게 됨.
    • 깊은 복사 : 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법
      • 깊은 복사 예시
      var user = {
        name: 'Minjeong',
        urls : {
            portfolio : 'github.com',
            blog : 'naver.com',
            facebook : 'facebook.com'
        }
      };
      
      var user2 = copyObject(user);
      
      user2.name = 'Jung';
      console.log(user.name === user2.name); //false
      
      user.urls.portfolio = 'portfolio.com';
      console.log(user.urls.portfolio === user2.urls.portfolio); // true
    • 상단 코드는 urls의 내부 프로퍼티들은 기존의 데이터를 그대로 참조하고 있어 내부 값들은 변경되지 않음.
    • 이를 위해 user.urls 프로퍼티도 불변 객체로 만들어야함.
    • var user2 = copyObject(user); user2.urls = copyObject(user.urls);
    • 이러한 과정을 참조형 데이터가 있을때마다 재귀적으로 수행해야 깊은 복사라 할 수 있음.
    • var deepCopyObject = function (target) { var result = {}; if (typeof target === 'object' && target !== null) { // typeof와 object로 타겟이 'object'형인지 볼 수 있나보군 // target !== null 을 넣은 이유는, typeof 명령어가 null에 대해서도 'object'를 반환하기 때문 for (var prop in target) { result[prop] = deepCopyObject(target[prop]); } } else { result = target; } return result; };
    • 깊은 복사를 처리할 수 있는 다른 방법
      • 객체를 JSON 문자열로 전환했다가 다시 JSON 객체로 바꾸는 것
      • httpRequest로 받은 데이터를 저장한 객체를 복사할 때 등 순수한 정보만을 다룰때 활용하기 좋은 방법
      • function deepCopyUsingJSON(target) {
        return JSON.parse(JSON.stringify(target));
        }
  1. undefined와 null
    1. ‘없음’을 나타내는 값
    2. undefined
      1. 사용자가 응당 어떤 값을 지정할 것이라고 예상되는 상황임에도 실제로 그렇게 하지 않을때 반환
        1. 값을 대입하지 않은 변수, 즉 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때
        2. 객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때
        3. return문이 없거나 호출되지 않는 함수의 실행 결과
      2. undefined 자체는 할당도 가능함. undefined 가 들어갈 주솟값을 확보하게됨.
      3. 따라서 자바 스크립트 엔진이 반환하는 경우를 제외하고는 undefined의 사용을 지양하는것이 좋음.
    3. null
      1. 비어있는 값 이라는 뜻
      2. 사용 시 주의점
        1. typeof null 이 object이기 때문에 (자바스크립트 자체 버그) null인지 여부를 판단하기 위해서는 동등 연산자(==)가 아닌, 일치 연산자 (===)를 사용해야 함.
Comments