# Variable / Hoisting / Data Type

## 1. Use Strict : 엄격 모드

```javascript
//Use strict!
//added in ES 5
//use this for Vanilla Javascript

'use strict';
```

## 2. Variable : 변수, 변경될 수 있는 값

{% hint style="success" %}
#### Variable, read & write : 메모리의 값을 읽고 쓰기가 가능
{% endhint %}

```javascript
//let (added in ES6)

let name = 'ellie';
console.log(name); //ellie
name = 'hello';
console.log(name); //hello
```

### 2-1. Block scope / global scope

| scope        | type                          | Description   |
| ------------ | ----------------------------- | ------------- |
| Block scope  | { } 블럭 안에 코드를 작성하는 변수         | 밖에서 접근이 되지 않음 |
| Global scope | 블록을 쓰지 않고 파일 안에 바로 정의해서 쓰는 변수 | 어디에서나 접근 가능   |

```javascript
//block scope
{
    let name = 'ellie';
    console.log(name);
    name = 'hello'; 
    console.log(name);
}

//global scope
let globalName = 'global name';
```

### 2-2. var를 사용하면 안 되는 이유

1. 선언도 하기 전에 값을 할당함
2. 값을 할당하기 전에도 출력이 됨
3. **var hoisting**?!
4. Block scope 이 없음 → 아무리 블록 안에 변수를 선언해도 밖으로 나와버림

{% hint style="danger" %}
**var hoisting** (move declaration from bottom to top) \
어디에 선언했는지 상관없이 항상 제일 위로 선언을 끌어올려 버리는 것
{% endhint %}

## 3. Constant : 상수, 한 번 할당하면 값이 절대 바뀌지 않음

{% hint style="success" %}
#### Constant, read only : 값을 할당하면 읽기만 가능, 다시 다른 값을 쓰는 것이 불가능
{% endhint %}

### " Favor Immutable Data type Always "

> **constant**는 변하지 않는 값으로, 개발자들이 선호하는 **immutable data type**

1. **security - lock the key from virus** : 해커들이 몰래 이상한 값을 넣는 것을 방지 할 수 있음
2. **thread safety** : thread들 동시에 변수에 접근해서 값을 변경할 수도 있기에, constant가 이를 방지해 줌&#x20;
3. **reduce human mistakes** : 실수를 방지하여 편리한 유지보수가 가능

| Type           | Typical Variable | Kinds                                    |
| -------------- | ---------------- | ---------------------------------------- |
| Immutable Type | const            | primitive types, frozen objects          |
| Mutable Type   | let              | all objects by default are mutable in JS |

```javascript
const dayInWeek = 7;
const maxNumber = 5;
```

## 4. Variable types : 데이터 타입

{% tabs %}
{% tab title="기본 데이터 타입" %}
**Primitive Type** : 더 이상 작은 단위로 나눠질 수 없는 한 가지의 작은 아이템(single item)

* number
* string
* boolean
* null
* undefined
* symbol
{% endtab %}

{% tab title="객체 타입" %}
**Object Type** : 기본 데이터타입을 여러 개 묶어, 한 단위로 관리할 수 있게 해주는 것(box container)

기본 데이터 타입 이외의 값은 모두 객체 타입으로, JS를 이루고 있는 모든 것이 객체!
{% endtab %}

{% tab title="함수" %}
**function** : 데이터 타입 중의 하나로, first-class function이 지원 됨

**first-class function?**\
함수도 다른 데이터 타입처럼 변수에 할당이 가능\
→ 함수의 parameter, argument로 전달 가능\
→ 함수에서 return type으로도 함수에 return이 가능
{% endtab %}
{% endtabs %}

{% hint style="success" %}
**Primitive Type** = **value로 값이 저장됨** \
ex) let name → ellie&#x20;

**Object Type** = 실제로 object를 가리키는 **reference 메모리에 저장됨** \
ex) const ellie 객체 할당 → reference → name / age → ellie / 20
{% endhint %}

{% tabs %}
{% tab title="number" %}
```javascript
const count = 17; //integer(정수)
const size = 17.1 //decimal number(소숫점)
console.log(`value:${count}, type:${typeof count}`);
console.log(`value:${size}, type:${typeof size}`);
```
{% endtab %}

{% tab title="infinity, NaN" %}
```javascript
const infinity = 1 / 0;          //infinity
const negativeInfinity = -1 / 0; //-infinity(네거티브 인피니티)
const nAn = 'not a number' / 2;  //NaN(not a number)
```
{% endtab %}

{% tab title="bigInt" %}
**bigInt** : **길이의 제약 없이** 정수를 다룰 수 있게 해주는 숫자형

\- Chrome과 Firefox에서만 지원 됨 (fairly new, don't use it yet)\
\- 정수 끝에 **n**을 붙이거나 함수 bigInt를 호출하면 됨

```javascript
const bigInt = 1234567890123456789012345678901234567890n; //over(-2*53 ~ 2*53)
```
{% endtab %}

{% tab title="string" %}
```javascript
const char = 'c';
const brendan = 'brendan';
const greeting = 'hello' + brendan;  //string + 변수
console.log(`value : ${greeting}!`); //${변수}
const helloBob = `hi${brendan}!`;    //``백틱 - template literals(string)

console.log (`value: ${helloBob}, type:${typeof helloBob}`);
console.log('value: ' + helloBob + 'type:' + typeof helloBob);
```
{% endtab %}

{% tab title="boolean" %}
**false** : 0, null, undefined, naN, ' '\
**true** : any other value

```javascript
const canRead = true;
const test = 3 < 1;

console.log (`value:${canRead}, type:${typeof canRead}`);
//value:true, type:boolean

console.log(`value:${test}, type:${typeof test}`);
//value:false, type:boolean
```
{% endtab %}

{% tab title="null & undefiend" %}
**null** : 변수를 선언하고 빈 값을 할당한 상태(빈 객체)\
**unedfined** : 변수에 값이 할당되지 않은 상태

```javascript
//null
let nothing = null;
console.log (`value:${nothing}, type:${typeof nothing}`);
//value:null, type:object

//unedfined
let x;
console.log (`value:${x}, type:${typeof x}`);
//value:undefined, type:undefined
```
{% endtab %}

{% tab title="symbol" %}
**symbol** : 고유한 식별자가 필요하거나, 우선순위를 줌\
주어진 string에 상관없이 고유한 식별자를 만들 때 사용되어 짐

\*주의\
심볼 바로 출력하게 될 때 에러가 발생하게 됨\
&#xNAN;**.description**을 이용해 **string으로 변환**하여 출력해야 함

```javascript
const symbol1 = Symbol('id');
const symbol2 = Symbol('id');
console.log(symbol1 ===symbol2); //false

const gssymbol1 = Symbol.for('id');
const gssymbol2 = Symbol.for('id');
console.log(gssymbol1 ===gssymbol2); //true

console.log(`value: ${symbol1.description}, type: ${typeof symbol1}`);
//value: id, type: symbol
```
{% endtab %}
{% endtabs %}

## 5. Dynamic typing (동적타이핑, Dynamically typed language)

> JS는 선언 시 어떤 타입인지 선언하지 않고 프로그램이 동작할 때 **할당 타입이 변경될 수 있음**

```javascript
let text  = 'hello';
console.log(`value : ${text}, type : ${typeof text}`);
// value : hello, type : string
text = 1;
console.log(`value : ${text}, type : ${typeof text}`);
// value : 1, type : number

text = '7' + 5; //string + number = ? 
console.log(`value : ${text}, type : ${typeof text}`);
// value : 75, type : string\
// 5를 string type으로 변환해서 string + string이 됨

text = '8'/ '2';
console.log(`value : ${text}, type : ${typeof text}`);
// value : 4, type : number(문자를 나누었지만 숫자값으로 타입이 변경됨)
```
