목차
Var 예약어
1. 호이스팅
2. 재선언 및 재할당
3. 함수 레벨 스코프 / ( let , const : 블록 레벨 스코프 )
var 예약어
ES6 전의 자바스크립트에서 변수를 선언하는 방법은 var 키워드 하나뿐이었다.
이에 상수를 선언하는 방법( ES6 이후부터는 const)이 없었다.
var예약어는 다음과 같은 특징이 있다.
- 호이스팅
- 재선언 (몇 번이고 선언할 수 있다.)
- 함수 레벨 스코프
이와같은 var의 특징으로 중복 선언 및 재할당이 가능하다.
이로 인해 보다 높은 자율성은 생기지만,
문제점으로 소스코드가 복잡해질 경우 기존 선언해둔 변수를 재선언, 혹은 재할당 할 수 있기 때문에
어떤 부분에서 값이 변경되는지 파악하기 힘들어질 수 있는 큰 문제점이 있다.
1. 호이스팅
hoisting : 끌어 올린다.
상황에 따라 변수의 선언과 할당을 분리해서 선언 부분을 스코프의 가장 위쪽으로 끌어올리는 것이다.
자바스크립트 인터프리터는 함수 소스를 보고 var를 사용한 변수는 기억하고 있기 때문에
아래와 같이 “선언한 것과 같은” 효과가 나타난다.
(undefined : 선언은 되었지만 값이 할당되지 않은 상태.)
testHoisting1 = () => {
// 변수 b 선언 후 b 호출
var a = 10;
var b;
console.log(`var a : ${a}`);
console.log(`선언 b : ${b}`);
};
testHoisting2 = () => {
// b호출 후 b 선언 및 할당
var a = 10;
console.log(`var a : ${a}`);
console.log(`선언 b : ${b}`);
var b = 20;
};
testHoisting1();
testHoisting2();
변수의 초기화는 코드상의 위치에 그대로 존재하지만, var를 사용한 변수는 함수의 맨 위로 끌어 올려진다.
이에 var로 선언한 변수는 함수 어디에서든 에러 없이 사용할 수 있게 된다.
일반적으로 코드에서 선언 되지 않은 변수가 있다면, 참조에러를 통해 에러를 출력해야 하는데
이를 호이스팅이 “선언한 것과 같은” 효과를 통해 에러를 출력하지 않으며 문제가 발생하게 된다.
에러 없이 사용하게 되면, 버그의 원인이 될 수 있다.
이에 에러가 나오지 않지만, 버그가 발생하여 유지 보수에 어려움을 겪게 된다.
이를 해결하기 위해 ES6 이후에서는 let을 사용하게 된다. ( 참고 : https://icea.tistory.com/49 )
[추가] let과 const에서도 호이스팅이 실행되지만, var처럼 undefined를 할당해주지 않는다.
var
testHoisting1 = () => {
var a = 10;
console.log(`var a : ${a}`);
console.log(`선언 b : ${b}`);
var b;
};
testHoisting1()
let
testHoisting2 = () => {
let a = 10;
console.log(`let a : ${a}`);
console.log(`선언 b : ${b}`);
let b;
};
testHoisting2()
const
testHoisting3 = () => {
const a = 10;
console.log(`const a : ${a}`);
console.log(`선언 b : ${b}`);
const b = 30;
};
testHoisting3()
let 과 const는 var처럼 호이스팅은 되지만, undefined로 초기화되지 않는다
이러한 이유는 TDZ(Temporal Dead Zone)으로 인해 변수를 사용할 수 없는 일시적인 비활성 상태로 만들기 때문이다.
2. 재선언 및 재할당
var 예약어를 사용한 변수는 재선언 및 재할당 가능하다.
이로인해 위에서 유지해야 하는 t 값(재할당, 재선언하면 안되는 값)이
다른 위치에서 t를 재선언, 재할당하며 기존 값을 변경해 버리게 된다면, 예상치 못한 결과가 만들어 질 수 있다.
또한 함수명과 변수명이 같은 상태로 선언 되었을 때, 변수가 함수값을 덮어쓰는 문제를 일으킬 수 있다.
testVar = () => {
console.log(`${test} :호이스팅 `); // 호이스팅
var test = 10;
console.log(`${test} :선언 `); // 선언
var test = "재선언";
console.log(`${test} :재선언 `); // 재선언
test = 20;
console.log(`${test} :재할당 `); // 재할당
};
testVar();
3. 함수 레벨 스코프 ( let , const : 블록 레벨 스코프 )
함수 레벨 스코프
var
function testVar() {
if (true) {
var varVariable = "hi Var";
console.log(`varVariable : ${varVariable}`);
}
console.log(`varVariable : ${varVariable}`);
}
testVar();
함수레벨스코프 var는 해당 var를 선언한 함수 내 어디서든 해당 변수를 사용할 수 있다.
반대로 블록레벨스코프인 let, const는 해당 변수를 선언한 블록 { } 내에서만 해당 변수를 사용할 수 있다.
(이외에 곳에서 호출 시 아래와 같이 레퍼런스에러가 발생한다!)
블록 레벨 스코프 : let, const
let
function testConst() {
if (true) {
const constVariable = "hi Const";
console.log(`constVariable : ${constVariable}`);
}
console.log(`constVariable : ${constVariable}`);
}
console.log(`constVariable : ${constVariable}`);
testConst();
const
function testConst() {
if (true) {
const constVariable = "hi Const";
console.log(`constVariable : ${constVariable}`);
}
console.log(`constVariable : ${constVariable}`);
}
console.log(`constVariable : ${constVariable}`);
testConst();
[참고]
ES6 부터는 변수 선언을 위한 예약어로 let과 const가 추가 되며 var 예약어는 사용하지 않도록 권장되고 있다.
var와 let, const와 가장 큰 차이점은 스코프의 범위이다.
var는 함수 영역의 스코프를 가지며, let과 const는 블록 영역의 스코프를 가진다.
스코프 | 선언 | 재할당 | 재선언 | 비고 | |
var | 함수 영역 | 가능 | 가능 | 가능 | 호이스팅 발생, 사용 지양 |
let | 블록 영역 | 가능 | 가능 | 불가능 | 값이 바뀌는 변수 |
const | 블록 영역 | 가능, 할당 | 불가능 | 불가능 | 변하지 않는 상수 변수, 선언 시 할당 필수 |
'Dev > 🟨 JavaScript' 카테고리의 다른 글
[JS] for, for of, for in을 정리해보아요. (0) | 2023.08.22 |
---|---|
[JS] 브라우저에서 자바스크립트는 어떻게 동작하는걸까? (0) | 2023.07.31 |
[JS] ES 6+ 문법을 정리해보아요. (0) | 2023.05.10 |
[JS] 데이터를 다루는 객체 사용 방법 (feat. 전개연산자 (ES6), Trouble Shooting) (0) | 2023.04.10 |
[Vite] 빛처럼 빠른 빁 ⚡ ( with. Vue 설치 ) (0) | 2023.03.27 |
[JS] JavaScript 문법 노트 ( map, set, || , nullish ) (0) | 2023.02.22 |
댓글