본문 바로가기
코드잇 스프린트 4기/위클리 페이퍼

[JavaScript] var, let, const

by devwqc 2024. 1. 20.

코드잇 스프린트 4기
4주 차 위클리 페이퍼

변수 선언

변수를 선언할 때 var, let, const 키워드를 사용할 수 있다.
예전에는 var를 사용했지만 var를 사용했을 때의 단점 때문에 letconst를 권장한다.

재선언, 재할당

var let const
재선언 가능 불가능 불가능
재할당 불가능 가능 불가능
// var
var a = 'codeit';
var a = 'codeit sprint';
console.log(a); // 'codeit sprint'
a = 'codeit fighting';
console.log(a); // 'codeit fighting'

console.log('-----');

// let
let b = 'codeit';
// let b = 'codeit sprint'; // Identifier 'b' has already been declared
b = 'codeit sprint';
console.log(b); // 'codeit sprint'

console.log('-----');

// const
const d = 'codeit';
// const d = 'codeit sprint'; // Identifier 'd' has already been declared
// d = 'codeit sprint'; // Assignment to constant variable.
console.log(d); // codeit

스코프

스코프(scope)란 변수에 대한 유효범위를 뜻한다.

스코프는 크게 전역 스코프지역 스코프로 나눌 수 있다.

  • 전역 스코프: 어디서든 참조할 수 있는 범위.
  • 지역 스코프: 스코프를 만든 자신과 하위 스코프에서만 참조할 수 있는 범위.

변수의 측면에서 스코프를 보자면 전역 변수지역 변수로 나눌 수 있다.

  • 전역 변수: 전역 스코프에서 선언된 변수로 어디서든 참조할 수 있다.
  • 지역 변수: 지역 스코프에서 선언된 변수로 선언된 스코프와 하위 스코프에서만 참조할 수 있다.

자바스크립트에서 스코프의 기준은 함수 스코프블록 스코프가 있다.
var키워드 변수는 함수 스코프를 가진다.
let, const키워드 변수는 블록 스코프를 가진다.

함수 스코프와 블록 스코프

// 함수 스코프
function outer() {
  var a = 'codeit';
  function inner() {
    let b = 'codeit sprint';
    console.log(a); // 'codeit'
  }
  inner();
  console.log(b); // b is not defined
}
outer();
console.log(a); // a is not defined

// 블록 스코프
{
  var c = 'codeit';
  let d = 'codeit sprint';
}
console.log(c); // 'codeit'
console.log(d); // d is not defined

함수 스코프를 가진 var 키워드의 단점을 for문을 통해 살펴보자.

for (var i = 1; i <= 7; i++) {
  console.log(i); // 1 2 3 4 5 6 7
}
console.log(i); // 8

for (let j = 1; j <= 7; j++) {
  console.log(j); // 1 2 3 4 5 6 7
}
console.log(j); // j is not defined

for문에서 선언된 i는 전역 변수로 빠지기 때문에 for문 밖에서 i에 접근이 가능하다.

호이스팅

호이스팅이란 변수, 함수 등의 선언부가 최상단으로 끌어올려지는 현상을 뜻한다.
정확히는 실행 컨텍스트가 미리 변수, 함수 등의 식별자 정보를 수집하는 현상이다.

이러한 현상으로 변수를 선언하기 전에 변수를 호출하면 is not defined가 아닌 undefined가 출력된다.
보통 var는 호이스팅이 일어나고 let, const는 호이스팅이 일어나지 않는다고 생각한다.
하지만 var, let, const 모두 호이스팅이 발생하지만 변수가 생성되는 과정이 약간 달라서 let, const는 호이스팅의 영향을 받지 않는 것처럼 보인다.

console.log(a) // undefined
var a = 'codeit';
console.log(c) // c is not defined
console.log(b) // Cannot access 'b' before initialization
let b = 'codeit sprint';
console.log(d) // Cannot access 'd' before initialization
const d = 'codeit fighting';

위 코드에서 보면 b is not defined의 출력을 예상했지만 조금 다른 결과를 확인할 수 있다.

변수가 생성될 때 크게 세 가지의 과정을 거친다.

  • 선언 단계: 실행 컨텍스트가 변수의 식별자를 수집한다.
  • 초기화 단계: 변수의 식별자를 위한 메모리 공간을 확보하고 값을 undefined로 초기화한다.
  • 할당 단계: undefined로 초기화된 변수에 직접 할당한 값을 할당한다.

var 키워드는 선언 단계와 초기화 단계가 동시에 이루어져서 선언 전에 호출하면 undefined가 출력된다.
반면 let, const는 초기화 단계가 변수 선언문에 도달했을 때 이루어진다. 그래서 변수 선언문 전에 변수를 호출하면 it not defined가 아닌 Cannot access before initialization이 출력되는 것이다.

그래서 let, const는 스코프 내에서 변수 선언문 전에 호출할 수 없고 이 구간을 TDZ(Temporal Dead Zone)이라고 부른다.

let, const가 호이스팅이 된다는 걸 보여주는 예

let a = 'codeit';
function outer() {
  console.log(a); // Cannot access 'a' before initialization
  let a = 'codeit sprint';
}
outer();

호이스팅이 발생하지 않는다면 전역 변수 a의 값인 'codeit'이 출력되어야 하지만 Cannot access 'a' before initialization이 출력되는 것을 볼 수 있다.

정리

var키워드는 개발을 하면서 예상치 못한 문제들이 발생하기 때문에 let, const키워드를 사용하자.


감사합니다.

'코드잇 스프린트 4기 > 위클리 페이퍼' 카테고리의 다른 글

[HTTP] HTTP 메서드  (0) 2024.01.27
[JavaScript] 이벤트 버블링, 캡처링, 위임  (0) 2024.01.27
[JavaScript] 얕은 복사, 깊은 복사  (0) 2024.01.20
[Git] Git-flow  (0) 2024.01.12
[Git] 머지(merge)  (0) 2024.01.12

댓글