NOW OR NEVER

드림엘리 : Javascript - 4. Data type 본문

Front-End/Javascript

드림엘리 : Javascript - 4. Data type

LAURA 2021. 12. 3. 18:52
반응형

데이터 타입

  • 프로그래밍에서 가장 중요한 것 : 입력, 연산, 출력
    • 사용자에게 콘솔이나 UI에서 입력받은 데이터를 잘 처리하고 연산해서 알맞게 다시 사용자에게 출력해주는 것이 제일 중요, 물론 그데이터를 전송을 이용해서 서버로 보내고 다시 받아오는 것도 중요하다.
    • 연산을 하면서 CPU를 효율적으로 사용할 수 있도록 CPU에 최적화된 연산(logic)을 작성하는 것도 중요하고 메모리를 최소화해서 사용하는 것도 중요하다.

variable

  • rw(read / write) : variable은 메모리의 값을 읽고(read) 쓰는(write) 것이 가능하다. 그래서 변경이 가능한 값이다.
  • 변경이 가능한 값(mutable data type)
  • let : js에서 변수 선언할 수 있는 키워드, es6에서 추가되어진 키워드, var의 위험성을 방지하기 위한 새로운 변수 선언 키워드
  • application 실행시 application마다 쓸 수 있는 메모리가 할당되어 지게 되는데 그 메모리는 텅텅 비어진 박스와 같다. application마다 쓸 수 있는 박스의 갯수가 제한적으로 할당되어진다.
  • let이라는 키워드를 통해 변수를 정의하게 되면 한가지의 박스를 가리킬 수 있는 포인터가 생기는 거나 마찬가지이다. 그 변수가 가르키는 메모리 어딘가에 특정 값을 저장할 수 있다. 추후에 그 변수가 가르키는 메모리에 다른 값을 넣어서 저장할 수도 있다.
  • 가능하면 class, 함수, if나 for문 등 필요한 부분에서만 정의해서 쓰는 것이 좋다.
  • var 쓰면 안되는 이유
    • 대부분의 프로그래밍 언어는 변수를 선언하고 나서 값을 할당하는 것이 정상적이지만 js의 var의 경우 선언되기도 전에 값을 할당할 수 있고 값을 할당하기도 전에 출력이 가능하다(변수가 정의되어 있지만 값이 안들어가있어 undefined가 출력됨). 이러한 것은 정상적이지 않다.
    • var hoisting : 변수를 선언하기도 전에 값을 사용할 수 있는 것 즉, 어디에서 선언했느냐에 상관없이 항상 제일 위로 선언을 끌어올려주는 것을 말한다.
    • block scope가 없다 : var은 block을 철저히 무시한다. 블럭 안에서 var 이용해서 변수를 선언하여도 블럭 밖에서 접근이 가능하다. 아무리 저 깊은 곳에 block을 이용해서 변수를 선언해도 어디서나 아무 곳에서나 보일 수 있는 것이 var이다. 초창기에는 이런 유연성을 이용하여 금방 프로그래밍을 해서 대충 짜도 돌아가는 application을 만들었었지만 어느정도 규모 있는 프로그래밍을 하다보면 선언하지도 않은 값들이 할당되어져 있는 등의 이상한 일들이 발생한다. var 때문이라해도 과언이 아니다.

scope

  • 밖에서는 안이 보이지 않고 안에서만 밖을 볼 수 있다 라는 말만 이해하면 scope 이해 가능, 즉 js에서의 scope란 유리창에 틴티드 처리된 것과 똑같다고 생각하면 됨

Local scope

  • local variable : block 안에서 선언하면 지역 변수, 지역변수는 지역적이라서 안에서만 접근 가능
  • global variable : 어디에서나 접근 가능
  • closure : 중첩된 함수에서 자식의 함수가 부모 함수에 정의된 변수들에 접근이 가능한 것
    • 자식은 부모에서 정의된 것들을 확인할 수 있다. 하지만 자식 안에 정의된 것들은 부모에서는 확인이 불가능 하다.(error 발생)

block scope

  • { }를 이용해서(블럭을 이용해서) 안에 코드를 작성하게 되면 블록 밖에서는 더이상 블록 안에 있는 것들을 볼 수 없다. 즉, 블록 안에서 선언한 변수는 블록 밖에서 접근(호출)할 수 없다는 것이다.

global scope

  • 블록 즉 {}을 쓰지 않고 파일 안에다가 바로 정의해서 쓰는 변수를 지칭
  • 어느 곳에서나 접근 가능
  • application이 실행되는 순간부터 끝날 때까지 항상 메모리에 탑재되어 있기 때문에 최소한으로 쓰는 것이 좋다.

constant

  • r(read only) : 메모리의 값을 읽기만 가능하다. 그래서 const 선언함과 동시에 값을 할당한 뒤로는 자물쇠가 생겨 읽기만 가능하고 다시 다른 값으로 수정하는 것이 불가능 하다.
  • 변수의 값을 바꿔야만 할 중요한 이유가 없다면 웬만해선 constant로 작성하는 것이 좋음
  • 키워드 const
  • js에서 변수 선언할 수 있는 키워드
  • 한번 값을 할당하면 값이 절대 바뀌지 않는 것을 말함, 변경 불가(immutable data type)
  • 변수의 경우 변수가 메모리 어딘가에 할당된 박스를 가리키고 있어서 그 가리키는 포인트를 이용해서 값을 계속해서 바꿔나갈 수 있었다(mutable). 하지만 constant는 가리키는 포인트가 잠겨있다. 그래서 값을 선언함과 동시에 할당한 뒤로는 절대 다시는 값을 변경할 수 없다.
  • 웬만하면 값이 할당한 다음 값이 다시는 변경되지 않는 그런 데이터 타입을 사용해라(favor immutable data type always)
    • 보안상의 이유로 인해서(security) : 한번 작성한 값을 다른 해커들이 코드를 이상한 것을 삽입해서 값을 계속해서 변경해나가는 것을 방지할 수 있다
    • thread safety : 어플리케이션 실행시 한가지의 프로세스가 할당되고 프로세스 안에서는 다양한 thread가 동시에 돌아가면서 어플리케이션을 조금 더 효율적으로 빠르게 동작할 수 있도록 도와준다. 다양한 thread들이 동시에 변수에 접근해서 값을 변경할 수 있는 데 이 동시에 값을 변경한다는 것은 위험한 것이다. 그래서 가능하면 가능하면 값이 변하지 않는 immutable data type을 사용하는 것이 좋다.
    • reduce human mistakes : 앞으로 변경되어야 할 좋은 이유가 없다면 왠만해서는 immutable data type인 const를 이용해서 프로그램을 작성하는 것이 좋다. 이렇게 해야지 자신이 나중에 코드 변경하거나 다른 개발자가 코드를 바꿀 때도 그 실수를 방지해줄 수 있다.

Variable types

  • javascript data type

Immutable data type

  • data 자체를 절대 변경하지 못한다.
  • primitive type : 만약 laura 라는 string 정의하게 되면 그 laura를 통째로 메모리에 올렸다가 다른 string으로 변경이 가능하지만 laura라는 string 자체에서 u를 빼고 다른 것으로 바꾼다던지, 이 data 자체를 변경하는 것은 불가능하다.
  • frozen objects(object.freeze()) : object 중에서 꽁꽁 얼어있는 것들, 이런 object도 변경이 불가능

Mutable data type

  • 변경이 가능한 data type
  • object : laura 라는 object를 선언하고 나서 laura 안에 있는 이름이나 나이를 변경할 수 있다. 즉 object는 계속 스스로를 변경이 가능하다.
  • js에서는 대체적으로 모든 object는 변경이 가능하다. array 의 경우도 mutable data type이다. 하지만 다른 언어에서는 간혹 mutable array와 immutable array 두가지를 분리해서 data type이 따로 존재하는 경우도 있다.

값 저장 방식에 따라

primitive type

  • value로 값이 저장 : 값 자체가 메모리에 저장됨
  • 더이상 작은 단위로 나눠질 수 없는 한가지의 아이템을 칭함(single item)
  • number, string, boolean, null, undefined, symbol
  • number
    • js에서 숫자 할당시 number 만 있으면 됨 얼마나 데이터가 큰지 생각할 필요 없음, 심지어 number이라고 data type을 선언하지 않아도 됨 왜냐면 js에서는 type이 다이나믹하게 결정되기 때문에 그냥 할당만 해주면 끝이다. 단 typescript의 경우 data type 명시해줘야 함(크기는 신경x)
    • special number values
      • Inifinity : positive(+) value 값을 0으로 나누게 되면 무한대의 숫자값이 나옴(infinity)
      • -Infinity : negative(-) value 값을 0으로 나누게 되면 negative infinity값 나옴
      • NaN : 숫자가 아닌 경우 발생, 예로 string 값을 number 값으로 나누게 되면 NaN 값 출력
      • 중요한 이유 : DOM 요소를 js를 이용해서 position을 바꾸는 등의 다양한 계산을 해야할 때 나누고자 하는 값이 0인지 아닌지 숫자인지 아닌지 확인도 하지 않고 연산을 바로 하게 되면 Infinity나 NaN 값을 받을 수 있기 때문에 사용자에게 에러가 발생할 수도 있다. 그래서 항상 연산 시 그 값이 정말 valid한 값인지 확인하고 연산하는 것이 중요하므로 이 점들을 이해하고 사용하는 것이 좋다.
    • bigInt
      • js에서의 number는 -2의 53승부터 2의 53승 까지의 범위의 숫자만 표현 가능
      • 숫자 젤 마지막에 n만 붙이면 bigInt로 간주되어지게 됨
      • 최근에 추가되어진 type으로 chrome과 firefox에서만 지원됨, 다른 브라우저에서는 숫자 끝에 이상한 문자가 붙어있다며 에러가 뜸(지원x)
      • 흔하게 사용x
  • string
    • 다른 프로그래밍 언어에서 알파벳 한개만 들어있는 data type이 따로 있지만 js에서는 한가지의 글자든 여러개의 글자든 string type으로 할당됨
    • 일반 string과 다른 변수를 + 기호를 사용해서 string을 붙이는 것도 가능하다.(type도 string으로 됨)
    • templite literals(string)
      • 많이 쓰임
      • `  `를 이용해서 원하는 string을 적고 ${변수}을 이용하면 변수의 값이 string에 자동적으로 붙여져서 나오는 것을 확인 할 수 있다.
      • + 기호를 사용하게 되면 ''(quote)기호를 여러개 사용해서 번거롭지만 ` `을 사용하게 되면 이 안에 있는 띄어쓰기 등이 다 나타나기 때문에 더 간편하다.
  • boolean
    • false : 0, null, undefined, NaN, ''(빈문자열)
    • 3 < 1도 false로 출력, 이러한 expression들도 다 평가되어서 false 값으로 할당될 수 있다.
    • true : any other value 어떤 값이든 다
  • null : 명확하게 텅텅 비어 있는 empty 값이라고 지정해주는 것
  • undefined : 선언은 되었지만 아무것도 값이 지정되어 있지 않을 때 즉, 텅텅 비었는지 값이 들어가있는지 아직 정해지지 않은 상태이다.
  • Symbol()
    • map이나 다른 자료구조에서 고유한 식별자가 필요하거나 동시다발적으로 concurrent하게 일어날 수 있는 그런 코드에서 우선 순위를 주고 싶을 때, 정말 고유한 식별자가 필요할 때 사용됨
    • 식별자를 string을 통해 만드는 경우도 있는데 이 string은 다른 모듈이나 다른 파일에서 동일한 string을 썼을 때 동일한 식별자로 간주됨, 하지만 반대로 symbol 같은 경우 동일한 값을 이용해서 symbol을 만들어도 다른 symbol로 간주됨
    • 주어지는 string에 상관없이 고유한 식별자를 만들 때 사용
    • 프로그래밍할 때 유용
    • 동일한 symbol 만들고 싶을 때 : Symbol.for('string') 사용, 주어진 string에 맞는 symbol을 만들게 되면서 동일한 symbol을 갖게 할 수 있다.
    • ${}을 사용해서 symbol 출력할 경우 symbol 바로 출력 안되므로 symbol저장된변수.desscription 이렇게 써서 string으로 변환해서 출력할 수 있다.

object type

  • object를 가리키는 reference가 메모리에 저장 : 너무 커서 메모리에 한번에 다 올라갈 수가 없다. 그래서 변수 선언 후 object 할당시 그 변수가 가리키는 곳에는 레퍼런스가 존재, 이 레퍼런스는 실제로 object를 가리키고 있는 곳이다. 이 레퍼런스를 통해서 실제로 object가 담겨있는 메모리를 가리키게 되는 것이다. 즉 그 변수가 가리키는 포인터만 잠겨서 그 변수는 다른 object로 변경은 불가능하지만 object 속 값들은 변경이 가능하다.
  • 일상생활에서 보는 물건과 물체들을 대표할 수 있는 박스 형태를 말한다. 그냥 변수 이름은 아무것도 설명되지 않지만 object를 만들어서 그 안에서 변수이름과 값을 할당해 설명할 수 있다.
  • const 키워드로 정의된 object는 그 object 가리키는 포인터는 잠겨 있어 다른 object로 할당이 불가하지만 object 안에 있는 변수들이 존재하므로 object이름.변수이름 작성시 각각 변수가 가리키는 메모리에 다른 값으로 할당이 가능하다.
  • single item들을 여러 개 묶어서 한 단위 즉 한 box로 관리할 수 있게 해주는 것(box container)
  • function도 js에서는 하나의 data type
  • first-class function : first-class function이 있다는 것은 이 프로그래밍 언어에서는 function도 다른 데이터 타입처럼 변수에 할당 가능 그래서 함수의 parameter 인자에도 전달 가능하고 함수의 return type에서도 function을 return할 수 있는 것이 가능하다.

Dynamic typing

  • js는 dynamically typed language 라고 불린다. c 나 java의 경우 statically typed language (변수 선언시 어떤 타입인지 결정해서 타입을 같이 선언함)
  • 선언할 때 어떤 타입인지 선언하지 않고 프로그램이 동작할 때 할당된 값에 따라 타입이 변경될 수 있다.
  • 좋은 아이디어가 있을 때 빠르게 프로토타입을 만들 때 정말 유용하게 쓰일 수 있는 언어
  • 다수의 엔지니어들이 만들 때 등 규모가 있는 프로젝트를 만들 때 이런 dynamic typing 때문에 발등에 불똥이 떨어질수도 있다.
    • js는 runtime에서 type이 정해지기 때문에 변수에 지정된 값을 다른 타입들을 조합해서 연산해서 다시 지정하는 등 할 때 error가 runtime으로 발생하는 경우가 많다.
    • 이러한 문제점을 해결하고자 Typescript 출시
    • typescript : js 위에 type이 올려진 언어, js을 이용하면 바로 브라우저가 이해할 수 있어서 실시간으로 연동하여 볼 수 있지만 typescript의 경우 결국 브라우저가 이해할 수 있는 js로 transcomplier(ex b
      abel)을 이용해야 해서 실시간으로 보는 것이 어렵다. 그래서 js를 충분히 배우고 typescript로 넘어가는 것이 좋다.
Comments