let
키워드와 var
키워드
let
은 변수를 선언할 때 사용합니다.- 블록 스코프를 가집니다.
- 호이스팅이 됩니다.
- 단, 초기화 전까지는
Temporal Dead Zone
에 속합니다.
- 단, 초기화 전까지는
var
도 변수를 선언할 때 사용합니다.- 함수 스코프를 가집니다.
- 호이스팅이 됩니다.
- 초기화 전에도 참조가 가능하지만,
undefined
라는 값을 가지고 있습니다.
- 초기화 전에도 참조가 가능하지만,
함수 스코프의 특징
function foo() {
for (var a = 0; a < 10; a++) {
console.log(a);
}
console.log(`outside: ${a}`);
}
var
로for
문을 작성하고 외부에서a
를 참조해도 참조가 가능합니다.- 이는 함수 스코프라는 특성 때문입니다. 블록에 갇혀있더라도 함수 내에서는 변수를 계속 참조 가능합니다.
function foo() {
for (let a = 0; a < 10; a++) {
console.log(a);
}
console.log(`outside: ${a}`); // Uncaught ReferenceError: a is not defined
}
let
으로for
문을 작성하면, 외부에서a
를 참조할 수 없습니다.- 이는 블록 스코프라는 특성 때문입니다. 블록이 끝나면, 해당 변수를 참조할 수 없습니다.
var
의 클로저 문제
function bar() {
for (var a = 0; a < 10; a++) {
setTimeout(() => {
console.log(a);
});
}
}
- 위 함수의 결과는
10
만10
번을 출력하게 됩니다. - 그 이유는
var
의 함수 스코프 특성과setTimeout
내부에 있는 콜백 함수가 즉시 처리되지 않고비동기 작업 큐
에 머무르다 동기 작업이 끝난 후Event Loop
에 의해 처리된다는 점에 있습니다.setTimeout()
내부의 콜백 함수는 비동기로 실행되고, 이는 자바스크립트 엔진의 특성상비동기 작업 큐
에 넘겨져 콜스택에 있는 작업이 완료된 후Event Loop
에 의해 처리됩니다.var
로 선언된 변수가for
바깥에서 유효하다는 특성으로 인해 자바스크립트 엔진은console.log(a)
코드를 실행할 때, 당시a
에 들어있던 값을 이용하지 않고,a
의 참조를 이용합니다.
a
는 유효하나,비동기 작업 큐
에 있는 작업이Event Loop
에 처리되는 시점에는for
문이 모두 끝난 시점이라10
이라는 값을 가지게 됩니다.
function bar() {
for (let a = 0; a < 10; a++) {
setTimeout(() => {
console.log(a);
});
}
}
- 위 코드는
let
의 블록스코프에 의해 아마 모두가 의도한대로0~9
까지 숫자를 순차적으로 출력하게 됩니다.
var
의 호이스팅과 let
의 TDZ 특성
function foobar() {
console.log(a); // undefined
var a = 100;
}
var
는 자바스크립트 엔진에 의해 해석될 때, 호이스팅이라는 과정을 거칩니다.- 호이스팅은 코드에서 사용되는 변수나 함수의 이름을 보고, 해당 키워드를 맨 위로 끌어올리는 행위를 말합니다.
- 그래서 위 코드에서
console.log(a)
시점에a
가 존재하지 않음에도 에러를 내지 않고undefined
를 출력합니다.
function foobar() {
console.log(a); // Uncaught ReferenceError: Cannot access 'a' before initialization
let a = 100;
}
let
키워드도 동일하게 호이스팅 현상은 일어납니다.- 단,
let
으로 선언된 변수는 초기화 전까지는Temporal Dead Zone
이라는 영역에 있어 사용이 불가능합니다.- 만일 위처럼 사용한 경우에는
Uncaught ReferenceError
가 발생하게 됩니다.
- 만일 위처럼 사용한 경우에는
- 이렇게 명확하게 에러를 내주는 것은 프로그래머의 실수를 방지해줍니다.
반응형
'자바스크립트 > 인터뷰' 카테고리의 다른 글
자바스크립트의 TDZ (Temporal Dead Zone) 에 대해서 간단히 설명해주실 수 있나요? (0) | 2023.01.18 |
---|---|
switch 문에서 에러 없이 let 으로 변수를 재선언해보세요. (0) | 2023.01.18 |
pure function (순수 함수) 란 무엇인가요? (0) | 2023.01.18 |
Currying function (커링 함수) 이란 무엇인가요? (0) | 2023.01.18 |
unary function 이란 무엇인가요? (0) | 2023.01.17 |