본문 바로가기
JavaScript/엘리

JavaScript/엘리 - 3. 데이터타입, let vs var, hoisting

by SKim입니다 2020. 6. 14.

프로그래밍 언어에서 가장 중요한 것 - 입력, 연산, 출력

 사용자에게 콘솔이나 UI에서 입력받은 데이터를 잘 처리하고 연산해서

 알맞게 다시 사용자에게 출력해주는 것

 & 그 데이터를 서버로 전송해서 다시 받아오는 것

 

 이런 연산을 하면서 CPU를 효율적으로 사용할 수 있도록

 CPU에 최적화된 로직을 작성하는 것도 중요하고

 메모리를 최소화해서 사용하는 것도 중요

 

< 변수 >

variable.js

'use strict';

index.html

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="variable.js"></script>
</head>
<body>    
</body>
</html>

 

변수: 변경될 수 있는 값

변수의 선언 - let 이용 (ES6에 추가된 언어)

※ ES6 가르쳐줄게 = JavaScript 가르쳐줄게

 

'use strict';
let name = 'ellie';
console.log(name);
name = 'hello';
console.log(name);

name이라는 변수를 선언함과 동시에 ellie라는 값을 할당

hello를 할당

앱을 실행시키면 앱마다 쓸 수 있는 메모리가 할당된다.

메모리는 텅 빈 박스들이다.

→ 앱마다 쓸 수 있는 박스들의 갯수가 제한되어 할당된다.

 

 

 

< Block scope >

'use strict';
{
    let name = 'ellie';
    console.log(name);
    name = 'hello';
    console.log(name);
}
console.log(name);

괄호(Block) 안에 코드를 작성하면

밖에서는 블럭 안의 내용들을 볼 수 없게 된다.

 

반대로 블럭을 쓰지 않고 파일 안에 바로 정해서 쓰는 변수들을

Global scope라고 부르는데,

이 변수들은 어디에서나 접근 가능하다.

 

글로벌한 변수들은 앱이 실행되는 순간부터 끝날 때까지 항상 메모리에 탑재되어 있기 때문에

최소한으로 쓰는 것이 좋다.

가능하면 클래스나 함수, if나 for로 필요한 부분에서만 정의해서 쓰는 것이 좋다.

 

JavaScript에서 변수를 선언할 수 있는 키워드는 딱 하나 let이다.

ES6 전에는 var를 썼다. → 쓰지마!

 

이유 (1)

대부분의 프로그래밍 언어에서는

변수를 선언하고 나서 값을 할당하는 것이 정상적인데,

 

JavaScript var에서는 조금 미친 행동을 할 수 있다.

선언하기도 전에 값을 할당할 수 있고

값을 할당하기 저에 출력할 수도 있다. → undefined(변수는 정의되어 있지만 값이 아직 안 들어가 있네)

cf) let을 사용하면 같은 상황에 undefined가 아니라 에러가 뜨고, 에러가 나오는게 정상적이다.

 

이것을 var hoisting이라고 하고 가끔 면접에서 물어보는 경우가 있다.

"hoisting이 뭔가?"

"어디에 선언했는지 상관없이 항상 제일 위로 선언을 끌어올려주는 것"

 

console.log(age);

이렇게만 하면 변수가 정의되지 않았다는(not defined) 에러가 뜨지만,

 

console.log(age);
age = 4;
var age;

이렇게 하면 변수를 정의한 것이 끌어올려져서 다음과 같이 뜬다.

 

이유 (2)

var는 block scope이 없다.

= block을 철저히 무시한다.

 

초창기에는 이런 유연성을 이용해서 금방금방 프로그램을 대충대충 짜도 동작할 수 있는 앱을 만들었지만,

어느 정도 규모있는 프로젝트를 하다보면 선언하지도 않은 값들이 할당되어서 이상한 일들이 발생한다.

 

ES6 호환성 체크

https://caniuse.com/#search=es6

 

Can I use... Support tables for HTML5, CSS3, etc

About "Can I use" provides up-to-date browser support tables for support of front-end web technologies on desktop and mobile web browsers. The site was built and is maintained by Alexis Deveria, with occasional updates provided by the web development commu

caniuse.com

ES6은 메이저 브라우저들이 다 지원한다.

IE는 전 세계에서 1%도 안 되는 소수의 사용자들이 쓰고 있기 때문에 무시하고 개발하면 된다.

 

만약 정말 해야 한다면 바벨을 이용해서 ES6이상으로 개발하고

나중에 배포할 때는 ES5나 4로 내려서 개발하면 된다.

 

 

ES5는 최신 버전은 지원한다.

 

 

 

 

< 상수 >

상수: 한 번 할당하면 값이 절대 바뀌지 않는다.

값이 계속 변경될 수 있는 것 - Mutable Data type - let 키워드를 이용한 변수

변경이 불가능한 것 - Immutable Data type - const 상수

 

favor immutable data type always

= 웬만하면 immutable data type을 이용해라.

 

for a few reasons:

- security

  : 해커들이 코드를 삽입해서 값을 변경하는 것 방지

- thread safety

  : 앱이 실행되면 한 가지의 프로세스가 할당되고,

   그 프로세스 안에는 다양한 thread가 동시에 돌아가면서

   앱이 조금 더 효율적으로 빠르게 동작할 수 있게 도와준다.

   다양한 thread들이 동시에 변수에 접근해서 값을 변경할 수 있는데,

   이 값을 동시에 변경하는 것은 위험하다.

- reduce human mistakes

 

 

 

< Variable types >

어떤 프로그래밍 언어이든 primitive type과 object type으로 나뉜다.

 - primitive type - 더 이상 작은 단위로 나눠질 수 없는 한 가지의 아이템

 - single item - numberm string, boolean, null, undefined, symbol 등

 - object - single item들을 여러개 묶어서 한 단위/박스로 관리할 수 있게 해주는 것

 - function - JS에서는 함수도 데이터 타입 중 하나이다.

   JS에서는 first-class funtion이 지원된다.

   = function도 다른 데이터 타입처럼 변수에 할당이 가능하고,

     그렇기 때문에 함수의 파라미터 인자로도 전달이 되고,

     함수에서 리턴타입으로도 함수를 리턴하는 것이 가능하다.

 

cf) C언어 - 로우레벨 언어

  ∵ 개발자들이 프로그래밍을 짜면서 조금 더 세세하게 메모리를 관리할 수 있기 때문

    = '이 정도 사이즈의 메모리를 할당해야지'라는 것이 가능하다.

       ex) 숫자의 크기에 따라서 short, int, long을 미리 생각해서 결정해야 된다. - Java도 마찬가지

 

 

※ object - 일상행활에서 보는 물건과 물체들을 대표할 수 있는 박스 형태

그냥 변수 name, age는 아무 것도 설명하지 못하지만,

object를 만들어서 엘리의 이름은 엘리이고 나이는 스무살이라고 얘기할 수 있다.

엘리는 상수이기 때문에 한번 할당된 이 object는 변경 불가하다.

 

엘리는 상수이기 때문에 엘리가 가리키고 있는 메모리의 포인터는 잠겨있어서 다른 object로 할당 불가

엘리 object 안에는 name과 age라는 변수 존재

그래서 ellie.name, ellie,age 이런 식으로 하면

각각 포인트가 가리키고 있는 메모리에 다른 값으로 할당 가능

 

 

 

 

(1) number

그러나 JavaScript는 number하나면 숫자는 끝난다.

심지어 number라는 데이터타입을 선언하지 않아도 된다.

∵ 타입이 다이나믹하게 결정되기 때문에

  let a = 12; 이런 식으로 할당해주면 끝이다.

 

그럼 타입 스크립트에는 까다로운 타입이 추가되나?

타입 스크립트에서도 number이거 하나면 충분하다.

 let a: number = 12;

 

 

 

하지만 이 number에서도 조금 특별한 값이 미리 정해져 있다.

(대부분의 프로그래밍 언어에서도 동일하게 적용된다.)

 

∞, -∞, String/number

이 세 가지는 특별한 숫자의 값이다.

이것이 중요한 이유는, 나중에 DOM요소를 JS를 이용해서 포지션을 바꾼다든지,

다양한 계산을 해야될 때, 나누고자 하는 값이 0인지 아닌지, 숫자인지 아닌지 확인도 하지 않고

연산을 바로 하면 숫자가 이닌 ∞나 nAn을 받을 수 있기 때문에

사용자에게 에러라 발생할 수 있다.

∴ 항상 연산을 할 때 그 값이 valid한 값인지 확인하고 연산하는 것이 중요하다.

 

 

JS에서의 number는 -2^53~2^53까지 표현이 가능한데,

최근에 bigInt라는 타입이 추가되었다.

그래서 숫자의 제일 마지막에 n만 붙이면 bigInt로 간주된다.

 

이것은 최근에 추가되었기 때문에,

크롬과 파이어폭스에서만 지원이 되고

사파리에서 열어보면 인식하지 못한다.

 

 

 

(2) String

다른 언어에는 char도 있지만

JS에는 한 가지의 글자이든 여러개의 글자이든 다 String 타입으로 할당이 된다.

+를 이용해서 일반 string과 다른 변수를 붙일 수 있다.

 

template literals = template string: ' '와 ${ }를 이용하면 변수의 값이 자동적으로 붙여져서 나온다.

↑두 개는 같은 코드이지만 위의 방법이 더 간편하다.

 

null과 undefined의 차이

null - 내가 명확하게 너는 텅텅 비어있는 empty값이야. 너는 아무것도 아니야. 라고 지정

undefined - 선언은 되었지만 아무것도 값이 지정되어 있지 않다. 텅텅 비었는지 값이 들어있는지 정해지지 않은 상태.

이렇게 undefined라고 명확하게 할당해도 되고, let x;라고만 하고 값이 할당되지 않은 상태도 undefined이다.

 

symbol은 나중에 맵이나 다른 자료구조에서 고유한 식별자가 필요하거나

아니면 동시다발적으로 컨커런트하게 일어날 수 있는 코드에서 우선순위를 주고싶을 때,

정말 고유한 식별자가 필요할 때 쓰인다.

 

간혹 식별자를 string을 이용해서 쓰는 경우도 있는데,

이 string은 다른 모듈이나 다른 파일에서 동일한 스트링을 썼을 때

동일한 식별자로 간주된다.

 

하지만 반대로 symbol같은 경우는 이렇게 동일한 아이들을 이용해서 심볼을 만들었지만

이 두 가지의 심볼은 다른 경우이다.

symbol은 동일한 string을 작성했어도 다른 symbol로 만들어지기 때문에

주어지는 string에 상관없이 고유한 식별자를 만들 때 사용된다.

→ 나중에 프로그래밍할 떄 정말 유용하게 쓸 수 있다.

 

'string이 똑같다면 동일한' symbol을 만들고 싶다면 다음과 같이 하면 된다.

symbol은 바로 출력하게 되면 에러가 발생한다.

그러므로 .description을 이용해서 string으로 변환해서 출력해야 한다.

 

 

< Dynamic typing: dynamically typed language >

= 선언할 때 어떤 타입인지 선언하지 않고

 런타임 프로그램이 동작할 때 할당된 값에 따라서 타입이 변경될 수 있다.

 

→ 좋은 아이디어가 있을 때 빠르게 프로토타입을 하고 싶을 때 유연하게 쓸 수 있다.

but 규모 있는 프로젝트를 만들 때, 이것 때문에 발등에 불똥이 떨어지는 일이 한두 번이 아닐 수 있다.

 

cf) C나 Java는 statically typed language

    = 변수를 선언할 때 어떤 타입인지 결정해서 타입을 같이 선언

 

 

불똥 떨어지는 일 예시

 

'7'+5 → 문자열에 +가 있으니까 5를 string으로 변환해서 string+string을 해준다.

 

 

정말 위험한 것:

 

text라는 변수 이름을 통해서 타입이 string일 것이라고 예상해서

첫번째 캐릭터를 받아오려고 한다. → h 출력

그런데 누군가가 타입을 숫자로 바꿔버리면 함수를 호출할 때 에러가 발생한다.

 

JS는 런타임에서 타입이 정해지기 때문에

이것 때문에 에러가 런타임으로 발생하는 경우가 굉장히 많다.

 

 

그래서 이 다이나믹 타입때문에 하도 뒤통수를 많이 맞아서 타입 스크립트가 나오게 된다.

타입 스트립트는 자바 스크립트 위에 타입이 올려진 언어이다.

 

 

 

 

 

 

 

 

드림코딩 by 엘리

youtu.be/OCCpGh4ujb8

 

댓글