본문 바로가기
개발(Development)/JS(자바스크립트)

[JS] 자바스크립트 변수 생성 과정, 호이스팅 정리

by 카레유 2020. 10. 8.

# 자바스크립트의 변수

numOne = 1 처럼 값을 저장해둔 저장소.

필요할 때마다 numOne라는 이름으로 사용할 수 있다.

정확히는 38이라는 값이 저장된 메모리 주소(0x0773F542 등)를 저장하고 있다.

var numOne = 1;
console.log(numOne); // 1

 

 

# 변수의 생성

: var, let, const 키워드로 변수를 만든다

 

1) varES5 이전에 사용하던 변수 생성 키워드. 스코프 관련 이슈가 있음

var numTwo = 2;
console.log(numTwo); // 2

 

2) let: ES6 부터 나온 변수 생성 키워. 다른 언어랑 비슷하다.

let numThree = 3;
console.log(numThree); // 3

 

3) const: ES6 부터 나온 상수 생성 키워드. 일단 값을 할당하면 재할당 불가(객체가 할당된 경우, 프로퍼티 변경은 가능!)

const numFour = 4;
console.log(numFour); // 4

* const는 선언과 할당을 동시에 해야한다. 선언만 하면 에러가 발생한다.

const age;
// SyntaxError: Missing initializer in const declaration



# 자바스크립트 런타임

자바스크립트 코드를 실행하면, 위에서 부터 한줄씩 실행된다.

이를 런타임이라고 한다.



# 자바스크립트 '소스코드 평가과정'

런타임에 들어가기 전, 소스코드 실행을 위한 사전 준비작업을 한다.

이를 '소스코드 평가과정' 이라고 한다,

 

각종 선언문(변수, 함수 등)은 이때 미리 실행된다.

단, '선언'까지만 이루어지고, '할당(초기화)'은 런타임 환경에서 실행된다.



# 자바스크립트의 변수 생성 과정

자바스크립트의 변수 생성은 2Step으로 이루어진다.

1) 1Step(선언): 소스코드 평가과정에서 변수를 '선언'함.

2) 2Step(초기화): 런타임에 변수에 값을 '할당'함.

*단, var는 1step에서 변수를 선언하면서 undefined까지 할당한다.



# 변수 호이스팅(기본)

소스코드가 실행되기 전, 변수 선언은 미리 이루어진다.

특히 var 키워드는 런타임 전에 변수를 선언하면서 'undefined'가 할당된다.

그래서 변수를 선언하기 전에! 해당 변수를 참조할수 있게 된다.

 

// 이 코드는 오류 없이 실행 된다

console.log(var_01);
var var_01; // undefined

 

var_01 이 뒤에서 선언되었는데도!

console.log(var_01)는 잘 실행되어 undefined를 출력한다.

코드실행 런타임 전에 var_01 변수의 선언과 undefined의 할당이 이루어졌기 때문이다.

 

마치 수 선언문이 맨위로 끌어올려져(Hoisting) 실행되는 것처럼 보여서, 호이스팅 이라고 한다.



# 변수 호이스팅(심화)

let, const 등의 키워드도 호이스팅이 발생한다.

그러나 런타임 전에 '변수의 선언'만 이루어지고, 'undefined 할당'은 이루어지지 않는다.

런타임에 들어와서 변수 선언문을 실제로 만나야 undefined가 할당된다.

따라서 변수 선언 코드 앞에서는 참조가 불가능하다.

 

// 이 코드는 참조 오류가 발생한다

console.log(let_01); // ReferenceError: let_01 is not defined
let let_01;

 

런타임 전에 let_01 변수가 선언되긴 했으나, 할당된 값이 없기 때문이다.

호이스팅이 되지 않는 것처럼 보일 수 있다.

// 그러나 아래 코드를 보자

let name = '카레유'  // 전역변수 name에 '카레유'가 할당 됨
{
    console.log(name) // ReferenceError: name is not defined
    let name = '원빈';  // 블록 내에서 지역변수 name 선언

 

<실행 결과>

name은 전역 변수로 '카레유'가 할당 되어 있지만,

ReferenceError: name is not defined 오류가 발생한다.

 

블럭 내부 스코프에서 name이 다시 선언 되면서

우선 순위를 갖게 되었기 때문이다.

(런타임 전에 선언은 되었지만, 할당된 값이 없는 상태)

 

호이스팅이 발생하지 않았다면

전역변수에 할당된 '카레유'가 출력되었을 것이다.

 

위 코드는 let, const도 호이스팅이 발생한다는 증거다.

 

(참고) var, let, const는 물론, function, class 선언도 모두 호이스팅이 발생한다.

단, ES6에서 등장한 let, const, class는 런타임 전에는 선언만 이루어지기 때문에, 호이스팅이 발생하지 않는 것처럼 '보일뿐'이다.

어쨋든 특별한 경우를 제외하면, let, const, classs는 호이스팅을 크게 고려하지 않고 사용해도 될듯 하다.

 

 

* 자바스크립트의 코드 실행 단계와 변수 생성과정에 대해서는 다음글을 참고

[자바스크립트] 코드 실행 2단계와 변수/함수 생성 과정

댓글