var, let, const 에 대해 다시금 깨우치기

limhi·2024년 9월 2일
0

var

var 는 자바스크립트에서 가장 오래된 변수 선언 방법이며, 초기 자바스크립트 구현 방식 때문에 letconst 로 선언한 변수와는 다른 방식으로 동작합니다.

스코프 규칙

var 로 선언한 변수의 스코프는 함수 스코프이거나 전역 스코프이므로, 블록 밖에서 접근이 가능합니다. 이는 오래 전의 자바스크립트에서는 블록 수준 렉시컬 환경이 만들어지지 않았기 때문입니다.

👉 렉시컬 환경 (렉시컬 스코프) 이란?

JS가 어떻게 동작하는지 설명하는데 쓰이는 이론 상의 객체입니다. 값과 표현식이 표현되거나 참조 될 수 있는 현재 실행되는 컨텍스트를 의미합니다. 만약 변수 또는 표현식이 해당 스코프 혹은 상위 스코프에 있지 않다면, 사용할 수 없습니다.

함수가 시작될 때 처리가 되기 때문에 선언 위치와 상관없이 함수 본문이 시작되는 지점에서 정의됩니다.

호이스팅

이렇게 변수가 끌어올려 지는 현상을 '호이스팅' 이라고 부르는데요,

호이스팅❓

호이스팅은 선언한 위치와 상관없이 자유롭게 사용하기 위해 만들어진 기능이나, 때로는 의도치 않은 버그를 생성할 여지가 있으므로 의도적으로 사용하는 경우가 아니라면 호이스팅이 되지 않거나 TDZ(Temporal Dead Zone) 로 초기화되는 let, const, 함수 표현식을 사용하는 것이 우선적입니다.

var 로 선언한 모든 변수는 블록 ({}) 안에서 선언하더라도 함수의 최상위로 끌어 올려지기 때문에 함수 전체에서 접근할 수 있습니다.

console.log(a); // undefined
var a = 5;
console.log(a); // 5

위의 코드에서 console.log(a) 는 앞서 선언되지 않은 a 변수에 대해 undefined 를 출력합니다. 이는 변수 선언이 최상단으로 호이스팅되었기 때문입니다.

반면에, 선언은 호이스팅이 되지만 할당은 호이스팅이 되지 않습니다.

var phrase; // 함수 시작 시 처리됨 (호이스팅)
phrase = 'hello'; // 할당은 실행 흐름이 해당 코드에 도달했을 때 처리됨 (호이스팅 안 됨)

중복 선언

또한, 같은 변수를 여러 번 중복으로 선언할 수 있습니다.

console.log(a); // undefined
var a = 5;
console.log(a); // 5

var a = 10; // 중복 선언
console.log(a); // 10

이렇게 var 는 중복 선언이 가능하므로 가독성을 떨어뜨릴 수 있으며, 때로는 의도치 않은 동작을 유발할 수 있습니다.

let

letconst 는 ES6 에서 도입된 변수 선언 방법으로, var 와 비교했을 때 더 많은 이점이 있습니다.
왜 'let'으로 정의되었을까?

블록레벨 스코프

의도치 않은 버그를 생성할 여지가 있던 var 와는 달리, let 은 블록 레벨 스코프를 가지므로 let 으로 선언된 변수는 해당 블록 내에서만 접근할 수 있습니다.

if (true) {
    let a = 10;
    console.log(a); // 10
}
console.log(a); // ReferenceError: a is not defined

위의 코드에서 a 는 if 블록 내부에서만 유효하므로, 블록 외부에서 접근하려고 하면 ReferenceError 가 발생합니다.

호이스팅과 TDZ

변수 호이스팅이 발생하지 않는 것처럼 보이지만, 실제로는 TDZ(Temporal Dead Zone) 이라는 개념이 적용됩니다. 이는 변수가 선언되기 전에 접근할 수 없음을 의미합니다.

console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 20;

이 코드에서 b 는 선언되기 전에 접근하려 하였기 때문에 ReferenceError 가 발생합니다.

중복 선언 금지

var 와 달리 let 은 같은 블록 내에서 중복 선언이 금지됩니다.

let a = 10;
console.log(a); // 10

// 같은 블록 내에서 let으로 동일한 변수명으로 다시 선언하면 오류 발생
let a = 20; // SyntaxError: Identifier 'a' has already been declared

이처럼 let 은 같은 스코프 내에서 중복 선언을 허용하지 않으며, SyntaxError 가 발생합니다.

이처럼 let 은 블록 스코프, TDZ, 중복 선언 금지 등의 특성을 통해 코드의 안전성을 높여줍니다.

const

const 또한 let 처럼 블록레벨 스코프를 따르고 중복 선언이 금지되나, 몇 가지 중요한 특징때문에 주로 상수를 정의하는 데 사용됩니다.

선언과 초기화

const 로 선언한 변수는 반드시 선언과 동시에 초기화해야 합니다. 초기화를 하지 않으면 SyntaxError가 발생합니다.

const a = 1; // O
const a; // X, SyntaxError

위 코드처럼 const는 초기화 없는 선언이 불가능하므로, 항상 값을 할당해야 합니다.

재할당 금지

const 로 선언된 변수는 재할당이 금지되어 한 번 할당된 값은 변경할 수 없습니다.

const a = 20;
a = 30; // TypeError: Assignment to constant variable.

이 경우 a 에 새로운 값을 할당하려고 하면 TypeError가 발생합니다.

const로 선언한 변수가 객체를 참조하는 경우, 객체의 프로퍼티는 변경할 수 있습니다. 이는 객체 자체의 참조가 변경되지 않는 한 가능합니다.

const obj = { key: 'value' };
obj.key = 'newValue'; // O, 객체의 프로퍼티 변경 가능
console.log(obj.key); // newValue

obj = {}; // X, TypeError: Assignment to constant variable.

위 코드에서 obj의 프로퍼티는 변경할 수 있지만, obj 변수 자체를 다른 객체로 재할당하려고 하면 오류가 발생합니다.

이처럼 const는 선언과 초기화의 의무, 재할당 금지 등의 특징을 가지고 있으며, 주로 상수를 표현하는 데 유용하게 사용됩니다.


아래는 학습하며 작성했던 전체적인 마인드맵입니다 :)
정돈되어 있지 않던 지식이었던 var, let, const 에 대해 학습하며, 다시금 깨달을 수 있어 즐거웠던 경험이었습니다 😆

profile
null 사랑하지 않아 - 어반자카파

0개의 댓글