
[Javascript] var, let, const
zl존석동
·2022. 1. 28. 16:55
자바스크립트의 변수 키워드 var와 ES6 에 추가된 let, const 에 대해 공부해보자.
자바스크립트를 사용할 때 이유도 모르고 var 는 사용하지 않고 let 과 const 만 사용했던 기억이 있다.
각 키워드들이 어떤 성질을 가지고 왜 var 를 안 쓰는지 간단하게 기초적인 공부해보고 기록하였다.
자바스크립트에서의 변수
- 선언 -> 초기화 -> 할당의 단계를 거친다.
선언
- 변수명을 등록하는 것
초기화
- 값 저장이 가능하게 메모리 공간을 확보한다.
- 기본적으로 undefined 로 초기화 된다.
할당
- undefined 로 초기화 된 변수에 = 연산자를 이용해 값을 넣는 것을 말한다.
var a; // 선언
// undefined 로 초기화 됨.
var b = "hello" // 선언하며 할당
console.log(a); // undefined
console.log(b); // hello
다음과 같이 출력을 변수 선언 및 선언+할당 앞에 위치시킨다면 어떻게 될까?
에러가 안난다면 왜 에러가 안나는 것인지 호이스팅을 통해 알아보자
console.log(a); // ???
console.log(b); // ???
var a; // 선언
// undefined 로 초기화 됨.
var b = "hello" // 선언하며 할당
호이스팅
호이스팅(Hoisting) 이란?
자바스크립트 코드 실행 전에 변수의 선언과 함수의 선언이
자바스크립트 스코프 최상단으로 올려진 것과 같은 상태를 말한다.
자바스크립트 엔진이 코드 실행 전에 모든 선언들에 대해 스코프에 등록을 먼저 하기 때문에
선언 시점보다 앞에서 참조되거나 호출되어도 오류가 나지 않는 것이다.
정확히는 var 키워드의 변수와 함수 선언문일 경우에만 맨 위로 올려진 것 처럼 동작한다.
변수에서의 호이스팅
console.log(varA); // undefined
//console.log(letB); // error!
//console.log(constC); // error!
var varA = "varA";
let letB = "letB";
const constC = "constC";
console.log(varA); // varA
console.log(letB); // letB
console.log(constC); // constC
함수 선언식 vs 함수 표현식 호이스팅
함수선언();
// 함수표현(); - not a Function Error!;
function 함수선언() {
console.log("함수 선언");
}
var 함수표현 = () => {
console.log("함수 표현")
}
함수선언();
함수표현();
let, const, 함수 표현식은 Hoisting이 안 되는거 아닌가요?
공부하며 여러 글들을 염탐해보니 그런 의도로 작성하시지는 않았겠지만
호이스팅이 일어나지 않는다고 되어있는 곳들도 있었다.
하지만 결론부터 말하면 호이스팅 자체는 일어나는 것이 맞다는 쪽이 옳다고 생각하게 되었다.
호이스팅은 되었지만 let , const , 함수 표현식은 undefined 로 초기화 되지 않은 상태로
실제 선언하는 라인까지 가기전에는 사용할 수 없는 상태가 된다 라고 이해하였다.
TDZ - Temporal Dead Zone(일시적 사각지대) 에 머물러 있다가 초기화 라인에서 해제되는 것이라고 한다.
에러 메시지를 통해 호이스팅에 여부에 대한 차이를 확인해볼 수 있다.
console.log(declaration);
let declaration;
declaration 이라는 변수가 초기화 전이라 접근할 수 없다는 ReferenceError 를 보여준다.
var 였다면 undefined(초기화는 되어있음.) 를 출력했던 것과 비교된다.
선언조차 하지 않은 없는 변수를 출력하려고 하면 다음과 같이 정의되지 않았다 라는 ReferenceError를 보여준다.
함수 표현식에서도 차이를 알아보자.
exist();
var exist = () => {
console.log("I am here!");
}
'정의되지 않았다' 이런 에러를 기대했는데 exist 는 함수가 아니다 라는 에러를 보여준다.
즉 var exist; 라는 선언 자체는 호이스팅 되어있고
그 구현부인 함수자체가 변수에 아직 할당되지 않았는데 호출했기 때문에 함수가 아니라고 출력하는 것이다.
맨 위에 console.log(exist) 를 해보면 undefined 가 출력되는 것을 확인해 볼 수 있을 것이다.
호이스팅 효과가 있고 없고에 따라 var 와 let, const 가 차이가 있다는 것을 알게 되었다.
구체적으로 var, let ,const 에 어떤 차이가 있는지 더 알아보자
var
* ES6 이전에 있던 변수 키워드.
* 중복 선언이 가능하다
* 함수 레벨의 스코프
=> 함수 안에서 선언 되면 그 함수 안에서만 사용 가능하다.
=> 블럭 스코프에서는 사용이 가능하다.
=> 함수를 제외한 스코프에서 선언된 var 변수는 어디서든 사용 가능한 전역 변수가 된다.
그래서
var 의 무분별한 사용은 중복하여 선언이 가능하고 함수 외부에 선언하게 되면 어디서든 접근할 수 있게 되어버려
예측이나 유지보수가 어려워 예기치 못한 결과를 초래할 수도 있게 된다!
주석을 빼고 보면 어디서 어떻게 값이 변경될지 알아보기 힘들 것이다.
console.log(a); // undefined
var a = 5;
console.log(a); // 5
console.log(b); // undefined
if (1 == 1){
var a = 15;
var b = 24;
}
// 함수를 제외한 스코프에서 선언된 var 변수는 밖에서도 사용가능하다.
console.log(b); // 24
console.log(a); // 15
function fA() {
// 함수 내부의 a 이기때문에 외부와 상관 없다.
var a = a;
a = a;
a = 4;
}
console.log(a); // 15
fA();
console.log(a); // 15
let
* ES6 에서 등장하였다.
* 변수 선언은 중복해서 할 수 없고 재할당은 가능하다.
* 블록 레벨의 스코프
=> 블럭 내부에서 선언된 것은 내부에서만 사용 가능하다.
한결 변수 사용이 자바와 비슷해졌다!
let letA = 5;
// let letA = 5; // SyntaxError: Identifier 'letA' has already been declared
console.log(letA); // 5
if(1 == 1) {
// console.log(letA); // Cannot access 'letA' before initialization
let letA = 4;
let letB = "hello";
console.log(letA + " In If scope"); // 4 In If scope
}
if(1 == 1 ) {
console.log(letA + " 앞의 스코프에서 선언된 let 사용");
}
console.log(letA); // 5
// console.log(letB); // Cannot access 'letB' before initialization
const
- 역시 ES6 에서 등장
- 재선언은 물론 재할당도 금지된다. 선언만 하는 것도 불가능하다.
=> const A;
Uncaught SyntaxError: Missing initializer in const declaration
const name = 'pds'
// name = 'sdp' //Uncaught TypeError: Assignment to constant variable.
// 재할당이 안될 뿐 const 가 불변을 의미하지는 않는다.
const user = {
id: 'pds0309',
}
user.id = 'pp0309';
console.log(user) // { id: "pp0309" }
결론
기존 var 의 사용은 변수 스코프 자체를 너무 넓게 가지고 여러번 선언이 가능하며
어느 위치에서 사용되건 에러를 뱉지는 않아 예측불가능함을 선사해주었다.
var 사용을 let 으로 바꾸면서 변수 스코프를 좁히고 존재하는 변수에 대해서 재선언을 막아
사용할 위치에서 필요한 요구에만 맞게 사용할 수 있게 되어 안전해지고 효율적이어지지 않았나 생각해보게 되었다.
ref
var, let, const의 차이 ⏤ 변수 선언 및 할당, 호이스팅, 스코프
자바스크립트에서 var로 변수 선언이 가능했는데, 왜 const와 let이 나왔으며 이 둘의 사용을 권장할까? 이를 정확하게 알기 위해서는, 변수의 선언 및 할당 과정, 호이스팅, 스코프를 알아야한다.
www.howdy-mj.me
[JavaScript] 호이스팅(Hoisting)이란? - 하나몬
❗️호이스팅이란? 호이스팅은 코드를 실행하기 전 변수선언/함수선언을 해당 스코프의 최상단으로 끌어올리는 것이 아니다. 호이스팅은 코드가 실행하기 전 변수선언/함수선언이 해당 스코프
hanamon.kr
'Javascript' 카테고리의 다른 글
[Javascript] 구조 분해 할당 (0) | 2022.01.29 |
---|