POTATO THAT WANT TO BE HUMAN

[JavaScript] 변수와 호이스팅 본문

FRONTEND/JavaScript

[JavaScript] 변수와 호이스팅

녜힝 2022. 5. 24. 23:42
반응형

자바스크립트에서는 var. let, const 를 통해 변수를 선언합니다.

자바스크립트의 변수는 선언 후 초기화됩니다.

선언 : 변수명을 등록하고 자바스크립트 엔진이 변수의 존재를 인식하는 단계
초기화 : 값을 저장하기 위한 메모리 공간을 확보하고 초기화하는 단계. 이 단계에서 암묵적으로 undefined가 할당됩니다.

 

🤔 호이스팅 (Hoisting)

먼저 호이스팅에 대해 알아보겠습니다.

호이스팅이란, 함수 안의 변수 선언을 모두 최상단으로 끌어올려주는 JS 고유 기능입니다.

자바스크립트가 시작될 때 엔진에 등록되어있는 함수(선언문으로 만들어진 함수), var로 선언된 변수들을 가장 먼저 끌어올려 읽어둡니다. 실행 전에 미리 읽어두기 때문에 var 키워드를 사용하면 변수를 선언하기 전에도 읽어올 수 있습니다.

/* 유저가 입력한 코드 */
console.log(a); // undefined 출력
var a = 10;
console.log(a); // 10

위 예제가 호이스팅되는 순서는 다음과 같습니다.

/* 호이스팅 된 코드 */
var a;
console.log(a);
a = 10;
console.log(a);

이러한 순서로 실행되기 때문에 유저가 입력했을 때 처음엔 undefined가 출력되고 선언 후에 10이라는 값이 출력되는 것 입니다.

 

 

이제 var. let, const 각각의 특징에 대해 살펴보겠습니다.

 

🤔 var의 특징

 

1. var는 변수 선언 후 값을 등록하지 않으면 자동으로 undefined가 할당됩니다.

 

2. var를 사용하면 재선언(중복선언)이 가능합니다. 

var a = 0;
a = 1;  // 재할당
var a = 10;  // 재선언

재할당과 재선언은 다릅니다.

재할당은 이미 선언된 변수의 값을 다시 할당하는 것이고, 재선언은 한 번 선언했던 변수를 다시 선언하는 것입니다.

 

3. var는 블록 스코프가 아닙니다.

자바스크립트에서 변수를 선언하면 범위에 따라 지역변수, 전역변수 두가지로 나뉘어집니다. 변수를 선언한 곳이 블록으로 싸져있다면 지역변수, 블록 바깥이라면 전역변수 입니다. var 를 사용하면 블록 내부에서 선언되어도 전역변수로 인식되기 때문에, 바깥에 있는 전역변수를 다시 선언하면 지역변수가 아닌 전역변수, 즉 재선언으로 읽혀지게 됩니다.

var num = 1;  // 전역변수

if(true) {
    var num = 100;  // 전역변수 -> 재선언으로 읽혀짐 
}

console.log(num);  // 100

 

var를 사용하면 이러한 상황들로 인해 혼란이 가중될 수 있기 때문에 등장한 것이 let과 const 입니다.

 

 

🤔 let의 특징

 

1. let은 블록레벨 스코프이기때문에 블록내부에서 재선언이 아닌 각각 다른 변수로 인식됩니다.

let a = 'hello';  // 전역변수

if(true) {
    let a = 'hi';  // 지역변수
}

console.log(a);  // 'hello'

위 예제에서 if문 안에서 선언된 a는 지역변수로, 바깥에 있는 a와는 다른 변수로 인식됩니다.

그렇기때문에 블록 바깥에서 console.log(a); 를 찍어보면 'hi'가 아닌 'hello'가 출력되는 것을 확인할 수 있습니다.

 

2. 재선언은 불가능하지만 재할당은 가능합니다.

let a = 'hello';

let a = 'hi';  // 재선언 시 에러 발생
a = 'hi';  // 재할당 됨

console.log(a);  // hi

이미 선언된 a라는 변수를 다시 선언하게 된다면 에러가 발생합니다. 하지만 a의 값을 바꾸는 재할당은 가능하기 때문에 console.log(a); 를 찍어보면 재할당된 a값인 'hi'가 출력됩니다.

 

3. 선언 단계와 초기화가 같이 일어나지 않습니다.

( 변수 생성시, 선언과 초기화가 분리되어 진행되기 때문에 변수가 사용되기 전까지 초기화가 되지 않습니다. )

초기화되지 않은 변수를 미리 선언하게 되면 레퍼런스 에러가 발생합니다. 이는 선언과 초기화가 동시에 실행되지 않기 때문입니다. 호이스팅이 되어도 초기화 단계가 일어나지 않기 때문에 값을 읽어오지 못합니다. 그래서 let은 var와 다르게 암묵적으로 undefined가 할당되지 않습니다.

console.log(a);  // error 발생
let a = 'hello';
let hello;
console.log(hello);  // undefined

 

 

🤔 const의 특징

 

1. const는 재할당, 재선언이 모두 안됩니다. -> 상수 선언 시 사용됩니다.

const는 재선언도, 재할당도 안되기 때문에 변하지 않는 중요한 값들을 저장할 때 주로 사용됩니다.

 

2. 단, const 변수에 객체를 할당하면 프로퍼티 생성·수정·삭제가 가능합니다.

const user = {
    name: 'kim',
    age: 20
}

user.name = 'lee';
console.log(user);  // {name: 'lee', age: 20}

위 예제에서 const를 사용하여 user라는 객체를 선언했습니다.

user 내부 프로퍼티 중 name의 값을 수정하고 console.log(user); 를 찍어보면 name의 값이 변경된 것을 확인할 수 있습니다.

 

3. const도 블록 스코프로, 블록내부에서 재선언이 아닌 각각 다른 변수로 인식됩니다.

4. 변수 선언시 반드시 선언과 동시에 초기화시켜줘야 합니다.

var와 let은 변수만 선언해도 암묵적으로 undefined가 할당됐습니다. 하지만 const를 사용하면 변수 선언과 동시에 초기화를 함께 해줘야합니다.

비슷하게 변수 선언·초기화 전에 변수를 불러오게 된다면 레퍼런스 에러가 발생합니다. 이러한 에러가 발생하는 이유는, 호이스팅이 되는데 런타임 이전에는 실행되지 않기 때문에 '코드를 읽어오기 전에 초기화가 진행되지 않은 상태입니다.'라는 에러가 발생하게 됩니다.

 

반응형
Comments