공부/JavaScript

JavaScript 문법 종합 3주차(1)

뀨뿌뀨뿌 2023. 6. 12. 21:51

1. 데이터 타입 심화

  ⅰ. 데이터 타입의 종류(기본형과 참조형)

데이터 타입 종류(이미지 출처 : : https://velog.io/@imjkim49/자바스크립트-데이터-타입-정리 )

  • 자바스크립트에서 값의 타입은 크게 기본형(Primitive Type)과 참조형(Reference Type)으로 구분됨
    => 구분 기준은 값의 저장 방식 불변성 여부!!
  • 기본형에는 Number(숫자형), String(문자열), Boolean, null, undefined, Symbo(ES6에서 새롭게 추가됨) 이 있음
  • 참조형은 말그대로 어떠한 겂을 참조(refer)하고 있는것을 말함.
    본적으로 Object(객체)!! 객체의 하위요소로써 Array, Function,... 등이 있음
  • 기본형과 참조형의 구분기준
    • 복제의 방식 (값이 어떻게 저장되는지, 복제되는지)
      ✔ 기본형 : 값이 담긴 주소값을 바로 복제
      ✔ 참조형 : 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제
    • 불변성의 여부 (메모리 관점에서 봤을때 불변한지 아닌지 판단할 수 있음)
      기본형 : 불변성을 띔   => 불변하다!
      참조형: 불변성을 띄지 않음  => 불변하지 않다!
    • 불변성을 띈다라는 말을 이해하기 위해서는 메모리와 데이터에 대한 내용을 이해해야함!!

ⅱ. 메모리와 데이터 

  • 메모리, 데이터
    • 비트(bit)
      컴퓨터가 이해할 수 있는 가장 작은 단위   => 0, 1
      0과 1을 가지고 있는 메모리를 구성하기 위한 작은 조각을 의미함
      이 작은 조각들이 모여서 메모리가 만들어짐
    • 바이트(byte)
      0과 1만 표현하는 비트를 모두 찾기에 부담이 됨
         => 너무 많이 찾아야 하기 때문에 비효율적
       1개 -> 2개 ....-> 8개(새로운 단위: byte) => 비트를 8개 합쳐놓음
    • 메모리(memo + ry) 
      byte단위로 구성됨
      모든 데이터는 byte 단위의 식별자인 메모리 주소값을 통해서 서로 구분됨
      📍 64비트(8 byte) 메모리에 저장하는 법
      => 64bit를 8개의 byte로 분할하고, 각 byte를 메모리에 저장
           각 byte는 8개의 bit이므로 64bit 정수는 메모리에서 8개의 연속된 byte에 저장됨
    • java, c와 다른 javascript의 메모리 관리 방식(feat. 정수형)
      java, c와 같이 조금 예전에 나온 언어들은 변수형을 저장할 때, 변수의 크기 까지도 개발자가 지정해야 되는 경우가 있음
      숫자 8을 저장하는 방법
          1. JS: let a = 8  (8byte)
          2. JAVA
              ◻ byte a = 8 (1byte)
              ◻ short a = 8 (2byte)
              ◻ int a = 8 (4byte)
              ◻ long a = 8 (16byte)
      java 또는 c언어가 등장했을 때 숫자 데이터 타입은 크기에 따라 다양하게 지정해줘야 할 만큼 개발자가 handing할 요소가 많았고, javascript는 이런 부분에서 상당히 편리함
  • 식별자와 변수
    const testValue = 3
    📍 변수 = 데이터
    📍 식별자 = 변수명

ⅲ.  변수 선언과 데이터 할당

  • 할당예시 - 풀어쓴 방식과 붙여 쓴 방식 동일하게 동작!!
// 선언과 할당을 풀어 쓴 방식
var str;
str = 'test!'

// 선언과 할당을 붙여 쓴 방식
var star = 'test!'
주소(ex. 변수영역) ... 1002 1003 1004 1005 ...
데이터   변수이름: str
데이터: 5004번 주소
       
주소(ex. 데이터 영역) 5002 5003 5004 5005
데이터   //// ///// test    

◼ 위에 표에서 윗공간은 변수영역, 아랫공간은 데이터 영역으로 가정
var str을 먼저 셋팅을 한후 왼쪽부터 탐색을 시작하여 빈공간을 찾음 => 1002번에 데이터가 없는것을 확인하고 저장
변수에 저장될 데이터 test도 데이터 영역에서 왼쪽부터 탐색을 시작하여 빈공간을 찾음
     =>  5002, 5003이 비어있지 않다고 가정을 한다면 5004번에 데이터가 없는것을 확인하고 저장
5004번에 할당된 주소를 데이터 영역에 저장함

  •  값을 바로 변수에 대입하지 않는 이유( 무조건 새로 만드는 이유)
    • 자유로운 데이터 변환
      ✔ 이미 입력한 문자열이 길어지면?
      ✏ 숫자는 항상 8byte로 고정이지만, 문자는 고정이 아님(영문:1byte, 한글: 2byte)
           이미 1003 주소에 할당된 데이터는 변환하려 할때 훨씬 더 큰 데이터를 저장하려 한다면
           1004이후부터 저장되어있는 모든 데이터를 오른쪽으로 다 미뤄야함
    • 메모리의 효율적 관리
      ✔ 똑같은 데이터를 여러번 저장해야 한다면?
      1만개의 변수를 생성해서 모든 변수에 숫자 1을 할당하는 상황을 가정했을때, 모든 변수를 별개로 인식한다고 한다면, 1만개의 변수 공간을 확보해야함
      • 바로 대입하는 case
        ❗ 숫자형은 8byte고정 => 1만개 * 8byte = 8만 byte가 필요함
      • 변수 영역에 별도 저장하는 case
        변수 영역: 2byte 1만개 = 2만 byte (이해하기 위해서 변수 영역에 저장되는 데이터는 2byte로 가정)
        데이터 영역: 8byte 1개 = 8byte
        ❗ 총: 2만 8byte가 필요함

ⅳ.  기본형 데이터와 참조형 데이터

  • 메모리를 기준으로 생각하는 두가지 주요 개념
    • 변수 vs 상수  - 변수와 상수가 변경될 수 있음은 데이터를 저장할때 변수 영역
      변수 : 변수 영역 메모리를 변경할 수 있음
      상수 : 변수 영역 메모리를 변경할 수 없음
    • 불변하다 vs 불변하지 않다  - 불변한지 아닌지는 데이터 영역에서 메모리 변경!
      불변하다 : 데이터 영역 메모리를 변경할 수 없음
      불변하지 않다 : 데이터 영역 메모리를 변경할 수 있음
  • 불변값과 불변성(with 기본형 데이터)
// a라는 변수가 abc에서 abcdef가 되는 가정을 통해 불변성을 유추
// 'abc'라는 값이 데이터영역의 @5002라는 주소에 들어갔다고 가정
var a = 'abc';

// 'def'라는 값이 @5002에 추가 되는것이 아니고
// @5003에 별도로 'abcdef'라는 값이 생기고 a라는 변수는 @5002 -> @5003으로 주소가 변경됨
// 즉, 변수 a는 불변하다 할수 있음
// 이때 @5002는 더이상 사용되지 않기 때문에 가비지 컬렉터의 수거 대상이됨
a = a + 'def';

✔ 더이상 쓸모가 없어진 데이터들은 JavaScript 가비지 컬렉터가 수거하고 다님

❌ 가비지 컬렉터(garbage collector)
✔ 자바스크립트는 눈에 보이지 않는 곳에서 메모리 관리를 수행
✔ 우리가 만드는 모든 것들은 메모리를 차지하는데 더는 쓸모 없어지게 된 것들은 자바스크립트 엔진에서 처리됨
✔ 가비지 컬렉터의 목적
- 메모리 할당을 추적하고 할당된 메모리 블록을 더이상 필요하지 않게 되었는지 판단하여 회수하는 것

가변값과 가변성(with 참조형 데이터)

// 참조형 데이터는 별도 공간이 필요함 => obj1을 위한 별도 공간
var obj1 = {
	a: 1,
    b: 'bbb',
};

 

주소(ex. 변수영역) 1001 1002 1003 1004
데이터 obj
데이터 주소 @7103 ~
     
주소(ex. 데이터 영역) 5001 5002 5003 5004
데이터 1 'bbb'    
주소(ex. 참조형 데이터를 위한 공간) 7103 7104 7105 7106
데이터 a
데이터 주소 @5001
b
데이터 주소 @5002
   

첫번째 표에서 윗공간은 변수영역이고, 아래공간은 데이터 영역으로 가정
var obj을 먼저 셋팅을 한후 왼쪽부터 탐색을 시작하여 빈공간을 찾음 => 1001번에 데이터가 없는것을 확인하고 저장
두번째 표에서 7103에 a라는 프로퍼티를 7104에 b라는 프로퍼티를 세팅
데이터 영역 5001번에 1이라는 값을 세팅한 후 a의 데이터 주소 5001을 가져옴
 데이터 영역 5002번에 'bbb'이라는 값을 세팅한 후 b의 데이터 주소 5002을 가져옴
obj가 저장된 곳에 데이터 주소를 7103시작한다는 것을 알려주면됨

  • 기본형 데이터의 변수 할당 과정과 차이점 : 객체의 변수(프로퍼티) 영역의 별도 존재 여부
  • 참조형 데이터가 불변하지 않다(가변하다)라고 하는 이유
var obj1 = {
	a: 1,
    b: 'bbb',
};

// ⭐데이터 변경
obj1.a = 2;

✔ 변경할 값인 숫자 2를 데이터 영역에서 검색
없으면, 2를 새로 추가하고, 해당주소(ex. @5003)를 obj1을 위한 별도 영역에 바꿔서 넣어줌
📍 데이터 영역에 저장된 값은 여전히 불변값이지만, obj1을 위한 별도 영역은 얼마든지 변경이 가능함!!
   => 참조형 데이터를 불변하지 않다(=가변하다)라고 함!
📚변수와 상수를 구분하는 기준은 변수 영역이고, 가변하다 불변하다 나누는 기준은 데이터 영역, 이 데이터 영역에 obj1을 위한 별도의 영역도 포함이 됨!

  • 중첩객체의 할당
    • 자바스크립트에서 중첩객체란, 객체 안에 또 다른 객체가 들어가는것을 말함
    • 객체는 배열, 함수 등을 모두 포함하는 상위개념이기 때문에 배열을 포함하는 객체도 중첩객체라고 할 수있음
var obj = {
	x: 3,
	arr: [3, 4, 5],
}

 

 

주소(ex.변수를 위한 영역) 1001 1002 1003 1004 1005  
데이터 obj / @7103~          
주소(ex. 데이터를 위한 영역 5001 5002 5003 5004 5005
데이터 3 4 5      
주소(ex. obj를 위한 영역) 7103 7104 ...
데이터 x / @5001 arr / @8104 - @8106  
주소(ex. arr을 위한 영역) 8104 8105 8106 ...
  arr[0]요소 - @ 5001 arr[1] 요소 - @ 5002  arr[2] 요소 - @5003  
          ◼ 위에 첫번째 표에서 윗부분을 obj 변수를 위한 공간, 밑부분을 데이터를 위한 영역이라고 가정하고, 두번째 표는 obj를 위한 영역이라고 가정하고 세번째 표는 arr를 위한 영역이라고 가정


◼ var obj을 먼저 셋팅을 한후 왼쪽부터 탐색을 시작하여 빈공간을 찾음 => 1001번에 데이터가 없는것을 확인하고 저장
◼ obj를 위한 영역에 x와 arr을 세팅
◼데이터 영역 5001번에 3이라는 값을 세팅한 후 x의 데이터 주소 5001을 가져옴
◼ arr도 참조형 데이터이기 때문에 arr을 위한 영역을 생성한 후 arr의 0번째, 1번째, 2번째 요소가 들어갈 공간을 세팅해줌
◼ 데이터 영역에서 3을 찾아서 arr0번째 요소에 3의 주소값을 가져오고, 4와 5도 마찬가지로 왼쪽부터 탐색하여 5002, 5003번에 세팅한후 주소 값을 가져옴
◼ arr의 주소를 8104부터 입력해줌
◼ obj의 주소도 7103부터 입력해줌

  • 참조 카운트가 0인 메모리 주소 처리
    • 참조카운트란?
      ✔ 객체를 참조하는 변수나 다른 객체의 수를 나타내는 값
      참조 카운트가 0인 객체는 더 이상 사용되지 않으므로, 가비지 컬렉터에 의해 메모리에서 제거
    • 가비지컬렉터(GC, Garbage Collector)
      더 이상 사용되지 않는 객체를 자동으로 메모리에서 제거하는 역활
      자바스크립트는 가비지 컬렉션을 수행함으로써 개발자가 명시적으로 메모리 관리를 하지 않아도 되도록 지원
      자바스크립트 엔진에서 내부적으로 수행되며, 개발자는 가비지 컬렉션에 대한 직접적인 제어를 할 수 없음

  • 변수 복사의 비교
// STEP01. 선언
var a = 10;  // 기본형
var obj1 = {c: 10, d: 'ddd'};  // 참조형 

// STEP02. 복사
var b = a;  // 기본형
var obj2 = obj1;  // 참조형

 

주소(ex. 변수영역) 1001 1002 1003 1004 1005 ...
데이터 a / @5001 obj1 / @7013~ b / @5003 obj2 / @7103~    
주소(ex. 데이터 영역) 5001 5002 5003 5004 5005 ...
데이터 10 ddd 15 20    
주소(ex. obj1을 위한 별도 공간) 7103 7104 ...
데이터 c / @5001 d / @5002  
          ◼ a를 변수영역에 세팅한 후 데이터 10도 데이터 영역에 세팅한 후 주소값을 가져옴


◼ obj1라는 변수명을 세팅한 후 obj1을 위한 별도 공간에 c, d를 세팅
◼ c에 10이 들어있는 5001 주소값을 가져오고 d의 데이터 'ddd'는 데이터 영역에 없으니 새로 세팅 한후 5002 주소 값을 가져옴
◼ b를 세팅한후 a가 가지고 있는 주소를 복사!!
◼ obj2를 세팅한 후 obj1이 가지고 있는 주소를 복사!❗ 복사 이후 값 변경(아래의 코드)
◼ 15를 데이터 영역에 새로 세팅 하고 b의 주소값에 5001이 아닌 5003을 바꿔줌
◼ 20를 데이터 영역에 새로 세팅하고 c의 주소값에 5001이 아닌 5004로 바꿔줌
❓ 문제는?
b는 a를 복사했지만 a와 b는 다른 완전히 다른 값을 가지고 있음
=> why? a는 5001이 주소값, a = 10 . b는 5003이 주소값이므로 b = 15
obj1, obj2 둘다 주소값 7103
=> 주소를 바로 복사해버리면 obj2를 바꿧음에도 불구하고 obj1도 c가 5004, 20으로 바뀌게됨!!!!

  • 복사 이후 값 변경(객체의 프로퍼티 변경)
    • 기본형과 참조형의 차이는 복사한 후의 값 변경에서 이뤄짐
// STEP01. 선언
var a = 10; //기본형
var obj1 = { c: 10, d: 'ddd' }; //참조형

// STEP02. 복사
var b = a; //기본형
var obj2 = obj1; //참조형

b = 15;
obj2.c = 20;

❗ 기본형과 참조형의 변수 복사시 절차의 차이점
◼ 기본형
✔ 숫자 15라는 값을 데이터 영역에서 검색 후 없다면 생성
검색한 결과주소 또는 생성한 주소를 변수 영역 b에 갈아끼움
a와 b는 서로 다른 데이터 영역의 주소를 바라보고 있기 때문에 영향 없음
 참조형
✔ 숫자 20이라는 값을 데이터 영역에서 검색 후 없다면 생성
✔ 검색한 결과 주소 또는 생성한 주소 obj2에게 지정되어 있는 별도 영역(7103~)에 갈아끼움
✔ obj1도 똑같은 주소를 바라보고 있기 때문에 obj1까지 변경이 됨

// 기본형 변수 복사의 결과는 다른 값!
a !== b;

// 참조형 변수 복사의 결과는 같은 값! => 원하지 않았던 결과를 얻게됨
// 따라서, 가변하다는 것은 굉장히 위험함
obj1 === obj2;
  • 복사 이후 값 변경(객체의 프로퍼티 변경)
//기본형 데이터
var a = 10;
var b = a;

//참조형 데이터
var obj1 = { c: 10, d: 'ddd' };
var obj2 = obj1;

b = 15;
obj2 = { c: 20, d: 'ddd'};

 

 

주소(ex.변수영역) 1001 1002 1003 1004 1005 1006 ...
데이터 a / @5001 obj1 / @7103~ b / @5003 ojb2 / @8104 ~      
주소(ex. 데이터 영역) 5001 5002 5003 5004 5005 5006
데이터 10 'ddd' 15 20 'aaa'    
주소(ex. obj1을 위한 별도 공간) 7103 7104 ...
데이터 c / @5001 d / @5002  
주소(ex. obj2을 위한 별도 공간) 8104 8105 ...
데이터 c / @5004 d / @5005  

◼ 위에 저장된 표와 동일하게 작동한 후 obj2 값 변경
◼ obj2울 위한 별도의 공간을 생성 한 후 c와 d를 세팅한후 각각의 값의 데이터 주소를 가져옴
◼ obj2에 주소값 @8104~@8105를 넣어줌
📚 obj1과 obj2가 완전히 다른 값을 바라보게 됨

✔ 참조형 데이터가 가변값이라고 할때의 가변은 참조형 데이터 자체를 변경할 경우가 아니라, 그 내부의 프로퍼티를 변경할 때 성립한다고 할 수 있음