2022. 1. 6. 01:34ㆍ기술 개념 정리/JS
1. 변수 선언 방식
var name = 'byein'
console.log(name) // byein
var name = 'var'
console.log(name) // var
변수를 한 번 더 선언했지만 에러가 아니라 정상적으로 코드가 실행된다.
var 는 변수 선언이 유연하여 편리할 수 있지만 코드량이 많아지면 변수가 어디에서 어떻게 사용될 지 파악하기 어려우며 값이 쉽게 바뀔 위험이 존재한다.
이를 보완하기 위해 ES6 이후로 let 과 const 가 추가되었다.
let name = 'byein'
console.log(name) // byein
let name = 'var'
console.log(name)
// Uncaught SyntaxError: Identifier 'name' has already been declared
const name = 'byein'
console.log(name) // byein
const name = 'var'
console.log(name)
// Uncaught SyntaxError: Identifier 'name' has already been declared
var 와 달리 let 과 const 는 변수 재선언이 불가능하다.
let 과 const 의 차이점은 immutable 여부이다.
let name = 'byein'
console.log(name) // byein
let name = 'var'
console.log(name)
// Uncaught SyntaxError: Identifier 'name' has already been declared
name = 'js'
console.log(name) //react
const name = 'byein'
console.log(name) // byein
const name = 'var'
console.log(name)
// Uncaught SyntaxError: Identifier 'name' has already been declared
name = 'js'
console.log(name)
//Uncaught TypeError: Assignment to constant variable.
let 은 변수에 재할당이 가능하지만 const 는 변수 재할당이 불가능하다.
정리하면 다음 표와 같다.
var | let | const | |
변수 재선언 | O | X | X |
변수 재할당 | O | O | X |
2. 호이스팅(Hoisting)
JS 엔진은 선언과 실행을 구분해서 처리한다.
var a = 1;
이 코드는 var a 선언문과 a = 1 대입문으로 구분 가능하다.
컴파일 단계에서 var a 가 등장하면 컴파일러는 스코프 내에 변수 a가 존재하는지 검색한다. a가 있다면 컴파일러는 이 선언문을 무시하고, 없다면 컴파일러는 변수 a를 스코프 컬렉션 내에 생성하도록 요청한다. 대입문은 실행 직전까지 실행되지 않고 방치된다.
코드 실행 단계에서 엔진은 a = 1 대입문을 처리한다. 해당 변수가 현재 스코프 내에 있는지 검색하여 발견하면 대입을 실행한다. 현재 스코프에 없다면 엔진은 바깥 스코프를 거슬러 올라가 최종적으로 글로벌 스코프까지 검색한다.
컴파일 단계와 실행 단계에서 선언문과 대입문이 따로 처리되어 마치 선언문이 코드 상단으로 끌어올려지는 듯한 효과가 발생하는데 이를 호이스팅이라고 한다.
foo();
function foo() {
console.log(a);
var a = 2;
}
위 코드는 실행과 선언이 완전히 뒤집힌 코드지만 에러가 발생하지 않는다.
실행 시점에서 호이스팅이 발생하면 위의 코드가 아래 코드와 같이 동작하게 된다.
function foo() {
var a;
console.log(a); // undefined
a = 2;
}
foo();
function foo() 와 var a 가 끌어올려져 각 스코프의 상단에 위치하게 된다.
호이스팅으로 보는 var, let 차이
JS는 ES6에서 도입된 let, const를 포함하여 모든 선언(var, let, const, function, function*, class)을 호이스팅한다.
하지만 var 로 선언된 변수와 달리 let 로 선언된 변수를 선언문 이전에 참조하면 참조 에러가 발생한다.
console.log(foo); // undefined
var foo;
console.log(bar); // Error: Uncaught ReferenceError: bar is not defined
let bar;
let 로 선언된 변수는 스코프의 시작에서 변수의 선언까지 일시적 사각지대 (Temporal Dead Zone)에 빠지기 때문이다.
변수는 선언 단계 -> 초기화 단계 -> 할당 단계 에 걸쳐 생성되는데 var 로 선언된 변수는 선언 단계와 초기화 단계가 한 번에 이뤄진다.
// 스코프의 선두에서 선언 단계와 초기화 단계가 실행된다.
// 변수 선언문 이전에 변수 참조 가능.
console.log(foo); // undefined
var foo;
console.log(foo); // undefined
foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
하지만 let 로 선언된 변수는 선언 단계와 초기화 단계가 분리되어 진행된다.
// 스코프의 선두에서 선언 단계가 실행된다.
// 아직 변수가 초기화(메모리 공간 확보와 undefined로 초기화)되지 않았다.
// 변수 선언문 이전에 변수 참조 불가.
console.log(foo); // ReferenceError: foo is not defined
let foo; // 변수 선언문에서 초기화 단계가 실행된다.
console.log(foo); // undefined
foo = 1; // 할당문에서 할당 단계가 실행된다.
console.log(foo); // 1
위의 내용을 표로 정리하면 다음과 같다.

3. 참고자료
https://www.huskyhoochu.com/hoisting-var-let-const/
호이스팅과 var, let, const
자바스크립트 기본기이면서 매우 중요한 개념을 되짚어봅니다
www.huskyhoochu.com
https://velog.io/@bathingape/JavaScript-var-let-const-%EC%B0%A8%EC%9D%B4%EC%A0%90
var, let, const 차이점
JavaScript에서 변수 선언 방식인 `var, let, const` 의 차이점에 대해 알아보자. 1. 변수 선언 방식 우선, `var`는 변수 선언 방식에 있어서 큰 단점을 가지고 있다. 변수를 한 번 더 선언했음에도 불구하
velog.io
https://stephaniejoymills.com/variation-of-variables/
Variation of Variables - My Personal Website & Blog
A space for me to share my thoughts, questions, and attempts to answer said questions!
stephaniejoymills.com