
변수의 생성 과정은 다음과 같다.
let myName; // 선언
let age = 26 // 초기화
myName = 'jihoon'; //할당
자바스크립트에서는 var, let, const로 변수를 선언할 수 있다. 이 세 가지 타입은 어떤 차이점이 있을까?
var는 중복 선언이 가능하고, 재할당이 가능하다.
var jihoon1;
var jihoon1 = 1;
var jihoon1 = 2; //중복 선언
jihoon1 = 3; //값 재할당
console.log(jihoon1) // 3;
위와 같은 코드가 유동성이 높아 장점처럼 보일 수 있지만, var는 지양하는 것이 좋다.
프로젝트 볼륨이 커져 코드가 많아지면, 기존에 변수를 선언한 것을 잊어버려서 값을 재할당 하거나 재선언 하는 실수가 발생할 수 있다. 이러면 기존의 로직에 영향이 갈 수 있다.
let은 재할당은 가능하지만, var와는 달리 중복 선언이 불가능하다.
let jihoon1;
let jihoon1 = 1; // 중복 선언, error
jihoon1 = 3; //값 재할당은 가능
console.log(jihoon1) // 3;
const를 제외하고 let을 자주 사용한다.
var, let과 달리 중복 선언도, 값 재할당도 불가능하다. 그렇기에 반드시 값을 선언과 동시에 할당해야 한다.
const jihoon1 = 1; // 선언과 동시에 할당
const jihoon1 = 2; // 중복 선언, error
jihoon1 = 3; //값 재할당, error
console.log(jihoon1) // 1;
const는 constant(상수)를 의미한다. 상수란 변하지 않는 수를 의미하는데, 코드에서 변화하지 않을 변수에 대해 const로 선언한다.
스코프(scope)란, 변수에 접근할 수 있는 범위를 뜻한다. 전체적으로 접근할 수 있는 전역 스코프와 특정 스코프에서만 접근할 수 있는 지역 스코프가 존재한다.
자바스크립트에서는 함수 스코프와 블록 스코프 2가지 타입이 존재한다.
var의 경우 함수 스코프로, 함수 내에 선언 된 변수는 접근이 가능하다.
let과 const의 경우 블록 스코프로, 선언된 블록 안에서만 접근이 가능하다. 함수도 블록으로 정의하기에, 함수 스코프 안에서 변수를 선언했다면 매한가지로 접근 가능하다.
function functionScope() {
if (true) {
var x = 10;
}
console.log(x); // var는 함수 스코프로, 접근 가능
}
functionScope(); // Output: 10
function blockScope() {
if (true) {
let y = 20;
const z = 30;
console.log(y); // 블록 스코프로 접근 가능, 20
console.log(z); // 블록 스코프로 접근 가능, 30
}
console.log(y); // ReferenceError, 변수가 정의된 블록 스코프를 벗어나 접근 불가
console.log(z); // ReferenceError, 변수가 정의된 블록 스코프를 벗어나 접근 불가
}
blockScope();
MDN에선 아래와 같이 정의하고 있다.
JavaScript 호이스팅은 인터프리터가 코드를 실행하기 전에 함수, 변수, 클래스 또는 임포트(import)의 선언문을 해당 범위의 맨 위로 끌어올리는 것처럼 보이는 현상을 뜻합니다.
여기서 잘 봐야하는 것은 "끌어올려진 것처럼 보이는 현상"이다. 물리적으로 코드가 끌어올려진 것이 아니다.
자바스크립트 엔진이 전체적으로 코드를 읽고 실행 컨텍스트에 미리 기록을 하는데, 이 과정에서 함수나 변수의 선언부보다 위에 호출이 존재해도 error가 나지 않고 실행 되는 것이다.
💡 실행 컨텍스트란 실행 가능한 코드에 제공할 환경정보를 모아놓은 객체를 말한다. 실행 가능한 코드란 일반적으로 전역 코드와 함수 코드를 뜻한다.
아래의 예시 코드를 살펴보자.
hoisting_testFunction(); // 선언부보다 호출이 먼저 존재
const hoisting_testFunction = () => {
console.log("호이스팅")
}
hoisting_testFunction();
첫 함수를 호출하는 코드는 함수 선언부보다 위에 존재한다. 원래 과정이라면 위에서 아래로 흘러가는 동작 구조로 실행되지 않아야 한다. 하지만 호이스팅 개념으로 인해 첫 hoisting_testFunction은 실행이 된다.
자, 그럼 이제 다시 var, let, const를 알아보자.
var는 변수 호이스팅이 발생한다.
console.log(age); // undefined
var age = 26;
console.log(age); // 10
원래라면 첫 console.log는 error가 나야하지만, 자바스크립트 엔진이 선언만 돼 있는 age에 대해 undefined로 초기화 해두었기 때문에 에러가 발생하지 않는다.
let과 const도 마찬가지로 변수 호이스팅이 발생하는데, var와는 다른 방식으로 작동한다.
console.log(age); // ReferenceError
let age = 26;
console.log(age); // 26
var와 동일한 코드지만, 이 사이에는 시간적 데드존(TDZ, Temporal Dead Zone)이 생성 된다. 그래서 이 기간 동안 변수에 엑세스를 하면 ReferenceError가 발생한다.
let과 const로 변수를 선언하는 경우에는 초기화 과정이 변수 선언문을 만났을 때 수행한다. 따라서 값을 참조할 수 없기 때문에 호이스팅이 발생하지 않는 것처럼 보인다.