> For the complete documentation index, see [llms.txt](https://docs.sysout.co.kr/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.sysout.co.kr/web/develop-page/js/syntax/let-const.md).

# let, const

## var, let, const

기존에 사용하던 변수 선언 방식은 다음과 같이 var 키워드를 사용한다.

```javascript
var a = 10;
var b = "hello";
```

이 변수 선언 방식은 다음과 같은 문제가 있다.

* 변수의 중복 선언이 가능하다.
* 변수가 없는 경우와 변수가 선언만 된 경우 모두 undefined를 반환한다
* 함수 레벨 스코프를 가진다.

위 문제들을 해결하기 위하여 const와 let이라는 키워드가 등장하였다.

* const : 불변(immutable) 변수 선언 키워드
* let : 가변(mutable) 변수 선언 키워드

## var 중복 선언

```javascript
var a = 10;
var a = "hello";
var a = 12 + 345;
console.log(a);
```

위 코드를 실행하면 마지막에 선언한 a의 계산 결과인 357이 콘솔에 출력된다. 자유로운 자바스크립트 문법 체계에서는 문제가 되지 않을 수 있으나 이는 개발자를 혼란스럽게 만든다.

```javascript
var a = 10;
a = "hello";
a = 12 + 345;
console.log(a);
```

위와 같이 작성하면 a의 값이 변경되었음을 코드로 짐작할 수 있다. **const**와 **let** 키워드를 사용하면 중복 선언이 불가능하다.

```javascript
const a = 10;
const a = "hello";//Uncaught SyntaxError : Identifier 'a' has already been declared
const a = 12+345;//Uncaught SyntaxError : Identifier 'a' has already been declared
console.log(a);
```

```javascript
let a = 10;
let a = "hello";//Uncaught SyntaxError : Identifier 'a' has already been declared
let a = 12+345;//Uncaught SyntaxError : Identifier 'a' has already been declared
console.log(a);
```

## undefined 이슈

var로 변수를 선언할 경우 **undefined 이슈**가 발생할 수 있다.

```javascript
console.log(b);//undefined
var b;
console.log(b);//undefined
```

위 코드를 실행하면 변수 선언 전, 후가 동일하게 undefined가 나온다. 이는 var로 선언한 변수가 호이스팅(hoisting) 되기 때문이다.

> ### 호이스팅
>
> JavaScript에서 **호이스팅**(hoisting)이란, 인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미합니다. `var`로 선언한 변수의 경우 호이스팅 시 `undefined`로 변수를 초기화합니다. 반면 `let`과 `const`로 선언한 변수의 경우 호이스팅 시 변수를 초기화하지 않습니다.
>
> 호이스팅을 설명할 땐 주로 "변수의 선언과 초기화를 분리한 후, 선언만 코드의 최상단으로 옮기는" 것으로 말하곤 합니다. 따라서 변수를 정의하는 코드보다 사용하는 코드가 앞서 등장할 수 있습니다. 다만 선언과 초기화를 함께 수행하는 경우, 선언 코드까지 실행해야 변수가 초기화된 상태가 됨을 주의하세요.
>
> 출처 - MDN Web docs (<https://developer.mozilla.org/ko/docs/Glossary/Hoisting>)

호이스팅은 자바스크립트가 실행되는 가장 일반적인 방법이었으나, 프로그램이 점점 고도화되면서 변수에 있어서 가독성이 떨어진다는 단점이 발생하게 되었다.

const는 불변(immutable)이므로 반드시 값이 대입되어야 한다.

```javascript
const b;//Uncaught SyntaxError: Missing initializer in const declaration
```

또한, 중복 선언도 불가능하다.

```javascript
const b = "hello";
const b = "hi";//Uncaught SyntaxError: Identifier 'b' has already been declared
```

선언 전에 접근할 수도 없다.

```javascript
console.log(b);//Uncaught ReferenceError: b is not defined
const b = "hello";
```

let은 가변이므로 선언만 해도 문제가 발생하지 않는다.

```javascript
let b;//undefined
```

하지만 추가 선언을 하면 오류가 발생하므로 변수 선언은 한 번만 될 것이라 믿을 수 있다.

```javascript
let b;
let b;//Uncaught SyntaxError: Identifier 'b' has already been declared
```

let 역시 const와 마찬가지로 선언 전에 접근할 수 없다.

```javascript
console.log(b);//Uncaught ReferenceError: b is not defined
let b = "hello";
```

## var 함수 레벨 스코프

var 키워드로 선언된 변수는 함수 상단에 호이스팅된다.

<div align="left"><figure><img src="/files/LLJ9FVxy2fCnNuoCfQbJ" alt=""><figcaption></figcaption></figure></div>

위 이미지 코드대로 함수를 만들어 실행하면 다음과 같이 출력된다.

```
10 '홀수' undefined
```

하지만 이는 정상적인 출력이라 보기 어렵다. 코드에는 함수 뿐 아니라 if와 else같은 블록(block) 레벨 스코프도 존재하기 때문이다.

<div align="left"><figure><img src="/files/kCic2msH8vcAJOKb7scV" alt=""><figcaption></figcaption></figure></div>

현대 프로그래밍에서는 함수 레벨 스코프 뿐 아니라 블록 레벨 스코프도 중요하게 간주한다. 따라서 var로 변수를 선언하면 스코프의 혼동이 올 수 있어 명확한 코드 작성이 어렵다.

const 또는 let으로 코드를 변경하면 블록 레벨 스코프 범위로 제한하여 사용할 수 있으며, 선언 전에 접근할 수 없다.

<pre class="language-javascript"><code class="lang-javascript"><strong>function tmpFunc(){
</strong>    const a = 10;
    if(a % 2 == 0){
        const b = "짝수";
    }
    else {
        const c = "홀수";
    }
    console.log(a);//10
    console.log(b);//Uncaught ReferenceError: b is not defined
    console.log(c);//Uncaught ReferenceError: c is not defined
}
</code></pre>

## 결론

특별한 이유가 없다면 **const**와 **let**을 사용하여 변수를 처리하는 것이 좋다.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sysout.co.kr/web/develop-page/js/syntax/let-const.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
