스파르타코딩클럽 내일배움캠프 TIL22

한재창·2022년 11월 29일
1

1. 데이터타입의 종류

  • 기본형과 참조형 구분하는 기준
    • 복제의 방식
      • 기본형 : 값이 담긴 주소값을 바로 복제
      • 참조형 : 값이 담긴 주소값들로 이루어진 묶음을 가리키는 주소값을 복제
    • 불변의 여부

2. 데이터 타입을 이해하기 위해 필요한 배경지식

  • 메모리, 데이터
    • bit : 0과 1을 가지고 있는 작은 메모리 조각
      • bit 가 늘어날 때는 2의 배수로 늘어난다.
    • memory : bit 가 모여서 메모리가 된다.
    • byte : 너무 적고 많은 bit를 저장하면 비효율적이기 때문에 8개로 묶어서 저장한다.

💡 모든 데이터는 byte 단위의 식별자인 메모리 주소값을 통해서 서로 구분이 된다.

  • 식별자, 변수
    • 변수 = 데이터
    • 식별자 = 변수명

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

  • 변수를 선언하고 데이터를 할당할 때 과정

    • 변수 영역과 데이터 영역으로 나뉜다.
    • 변수 영역에는 식별자를 저장하고 데이터 영역에는 데이터를 저장한다.
    • 변수 영역에서 값으로 데이터 영역에 저장된 알맞은 주소를 가져온다.
  • 값을 바로 변수에 대입하지 않는 이유

    • 자유로운 데이터 변환 : 숫자는 상관없지만 문자열은 데이터의 길이가 길어질 수도 있기 때문에 변수 영역에 값을 저장하면 뒤에 있는 나머지 값들이 뒤로 밀리게 되서 굉장히 비효율적이게 된다.
    • 메모리의 효율적인 관리 : 똑같은 데이터를 한번만 저장해서 알맞은 주소를 가져오면 된다.

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

  • 불변값과 불변성
    • 데이터 영역의 메모리가 바뀌는 것이 아니라 새로운 데이터 영역에 새로운 데이터를 저장하고 변수 영역에서 주소값을 바꿔주는 것이다.
    • 가비지컬렉팅
      • 쓰레기를 모으는 것
      • 데이터 영역에서 사용되고 있다가 변수 영역의 값이 바뀜으로써 더이상 사용되지 않는 데이터 영역을 수거함, 수거된 공간은 빈 공간이 된다.

💡 변수 영역의 값이 바뀐다는 것은 데이터 영역의 주소가 바뀌는 것을 의미한다.

  • 변수, 상수를 결정하는 요소

    • 변수 영역에 있는 주소 값이 바뀔 수 있느냐를 묻는게 아닌 데이터 영역에 있는 값이 변경될 수 있는지를 묻는다.
    • 변수는 바꿀 수 있는 값 : let, var
    • 상수는 바꿀 수 없는 값 : const

  • 예시

    • 1 : b 의 값이 처음에는 5이기 때문에 데이터 영역 주소값 5003을 불러온다.
    • 2 : b 의 값이 5에서 7로 바뀌기 때문에 데이터 영역 주소값 5004를 불러온다.
    • 즉 b 는 변수이고, 데이터 영역에서 값이 바뀐게 아니므로 불변성이다.
  • 가변값과 가변성

    • 참조형 데이터의 변수 할당 과정 (1)
      • 오브젝트의 데이터 { 부터 } 까지 를 저장하기 위해서는 데이터 영역에서 한 공간에만 저장할 수 없다.
      • 따라서 객체의 변수 영역 즉, 프로퍼티 영역(obj1을 위한 별도 공간)에서 식별자 a, b를 저장한다.
      • 데이터 영역에 1, "bbb"를 저장해서 프로퍼티 영역에 값으로 데이터 주소를 가져온 뒤 프로퍼티 영역의 주소를 데이터 영역의 값으로 가져온다.
      • 데이터 영역의 주소를 변수 영역의 값에 주면 완료!
  • 참조형 데이터의 변수 할당 과정 (2)

    • 오브젝트 안에 arr 있으므로 arr 을 위한 영역도 있어야 한다.
    • arr 영역에 데이터 주소를 값으로 넣어주고 데이터 영역에 arr 영역의 주소를 저장한다.
    • 프로퍼티 영역에서 arr 의 값으로 데이터 영역의 주소를 준다.
    • 나머지는 위의 내용과 똑같다.

💡 기본형 데이터와 참조형 데이터의 차이점은 객체의 변수 영역의 별도 존재 여부이다.

  • 참조형 데이터가 가변한다고 하는 이유
    • 참조형 데이터의 변환은 데이터 영역의 빈 주소에 새로운 값을 저장하고 프로퍼티 영역의 값이 새로운 데이터 값의 주소로 바뀌는 것이다.
    • 변수 영역의 값이 바뀌는 것이 아니라 프로퍼티 영역의 값이 바뀌는 것이기 때문에 가변성을 띈다고 볼 수 있다.

5. 변수 복사

  • 값을 할당하고 복사하는 형식

  • 변수 영역에서 복사하고 싶은 변수 주소를 복사하는 것이 아니라 복사하고 싶은 변수와 똑같은 값의 주소를 값으로 지정해서 값을 똑같게 해주는 것이다.

  • 복사 이후 값 변경(객체의 프로퍼티 변경)

    • 프로퍼티 영역의 값을 데이터 영역에서 새로운 주소를 찾아 넣어준다.
// case 1
let a = 10;
let b = a;
b = 15;

// case 2
let obj1 = { c: 10, d: "ddd" }
let obj2 = obj1
obj2.c = 20
  • 예시
    • case 1
      • a === b 이다.
    • case 2
      • obj1 === obj2 이다.
      • 이유 : 변수 영역에서의 값이 같은 주소를 할당하고 있기 때문이다.
        프로퍼티 영역의 값이 주소 5001 에서 5004 로 변했기 때문에 obj1.c의 값도 20이 된다.
      • 문제 : obj2만 바꾸고 싶은데 obj1도 바뀌었다.
      • 답안 : 가변임을 유의해야 하고, 불변하도록 만들어야 한다.

불변 객체

let obj1 = { c: 10, d: "ddd" }
let obj2 = obj1
obj2.c = 20
  • 예시 (가변 객체)
    • 문제 : obj2만 바꾸고 싶은데 obj1도 바뀌었다.
    • 답안 : 가변임을 유의해야 하고, 불변하도록 만들어야 한다.
let obj1 = { c: 10, d: "ddd" }
let obj2 = { c: 20, d: "ddd" }
obj2.c = 30
  • 예시 (불변 객체)

    • obj2 = obj1 이 아닌 obj2 = { c: 20, d: "ddd" } 로 할당한다.
    • 프로퍼티 영역에서 바라보는 주소가 다르기 때문에 값을 바꾸어도 obj1 에게 영향이 없다.
  • 불변 객체의 필요성

    • 예시 1 (가변 객체)
      • input : user의 형식을 가지고 있는 객체, 바꿀 이름
      • output : 이름 바꿔서 복사한 그 객체
    • 예시 2 (비효율적인 코드)
      • 불변하게 하려면 새로운 객체를 return 해줘야한다.
      • 문제 : 프로퍼티가 2,3개 일때는 가능하지만 많은 수의 프로퍼티를 가졌을 때는 비효율적이라 쓰지 않는다.

for in(index를 가져온다) 을 활용한 코드
for 문을 돌면서 새로운 값을 넣어준다.
depth (1) = string, number 등 한개의 값
depth (여러개) = 객체(배열,함수 등)
depth가 여러개 일 때 값을 새롭게 생성을 못한다( for 문을 한번만 돌기 때문에 )

  • 얕은 복사 (더 나은 방법)

    • 바로 아래 단계의 값만 복사
    • 문제 : 중첩된 객체의 경우 참조형 데이터가 저장된 프로퍼티를 복사할 때, 주소값만 복사
    • 답안 : user.urls 프로퍼티도 불변 객체로 만들어야 한다. (깊은 복사)
  • 깊은 복사 (얕은 복사의 문제점 해결)

    • 객체의 프로퍼티 중, 기본형 데이터는 그대로 복사하고, 참조형 데이터는 내부의 프로퍼티를 복사 > 재귀적(다시 돌아간다) 수행
    • 내부의 모든 값들을 하나하나 다 찾아서 복사하는 방법 (depth 가 여러개여도 복사 가능)
    • 객체 타입이라면 자기 자신을 불러서 타겟안에 있었던 속성값을 호출한다.
  • JSON (더 쉬운 방법)

    • 어떠한 데이터의 틀을 만들어 놓은 것
    • object 타입으로 들어오면 JSON으로 만들어 줬다가 다시 object로 돌아간다. 이때 새로운 객체가 만들어진다.

undefined & null

let arr 1 = [];
arr1.length = 3;
console.log(arr1) // [ <3 empty items> ]

let arr2 = new Array(3)
console.log(arr2) // [ <3 empty items> ]

let arr3 = [undefined, undefined, undefined]
console.log(arr3) // [undefined, undefined, undefined]
  • undefinded
    • 사용자 지정
    • 자바스크립트 엔진에서 자동 부여
      • 변수에 값이 지정되지 않은 경우, 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때
      • 이나 []로 접근하려 할 때, 해당 데이터가 존재하지 않는 경우
      • return 문이 없거나 호출되지 않는 함수의 실행 결과
    • 비어있는 요소와 undefined 는 다르다.
    • forEach, map, filter, reduce 를 실행할 경우
      • empty(길이는 지정했지만 값이 없는 경우) > skip
      • undefined > 수행한다.
  • null
    • '없다' 를 명시적으로 표현할 때 사용한다.
    • typeop null 은 오브젝트 타입이기 때문에 if문을 쓸때 주의해야 한다.

🧐 좋은 개발자란 ? 효율화를 고려하여 코드를 짜야한다. ( 반복적인 부분을 줄여야 한다 > 유지보수하기 편하다. )

profile
취준 개발자

0개의 댓글