스코프와 호이스팅
변수가 보이는 범위를 알아보고, var 를 사용하지 않는 이유를 봅니다.
변수가 보이는 범위
변수는 아무 데서나 보이지 않습니다. 선언한 자리에 따라 보이는 범위가 정해지는데, 그 범위를 스코프(scope) 라고 합니다.
규칙은 하나입니다. 중괄호 안에서 선언한 것은 그 중괄호 안에서만 보입니다. 안쪽에서는 바깥을 볼 수 있지만, 바깥에서는 안쪽을 볼 수 없습니다.
같은 이름, 다른 자리
const name = "바깥"; function show() { const name = "안쪽"; console.log(name); } show(); console.log(name);
이름이 같아도 서로 다른 변수입니다. 함수 안에서는 가까운 것이 보입니다.
안쪽에서는 바깥이 보입니다
const tax = 0.1; function withTax(price) { return price + price * tax; } console.log(withTax(10000));
tax 는 함수 밖에 있지만 안에서 보입니다. 이렇게
여러 함수가 함께 쓰는 값은 밖에 한 번만 두는 편이 낫습니다.
중괄호면 모두 스코프입니다
함수뿐 아니라 if 와
for 의 중괄호도 스코프를 만듭니다.
if (true) { let inside = "블록 안"; console.log(inside); } console.log(typeof inside);
밖에서는 inside 가 없습니다. 그대로 읽으면 오류가
나므로 typeof 로 확인했습니다 —
typeof 는 없는 이름에도 오류를 내지 않습니다.
var 를 사용하지 않는 이유
var 는 let 이 생기기
전에 쓰던 것입니다. 중괄호를 스코프로 보지 않습니다.
function withVar() { if (true) { var x = "var 는 블록을 넘습니다"; } console.log(x); } withVar();
if 안에서 선언했는데 밖에서 읽힙니다. 반복문 안에서
만든 변수가 밖으로 새어 나가는 일이 생겨 찾기 어려운 버그가 됩니다. 새 코드에는
var 를 사용하지 않습니다.
호이스팅
JavaScript 는 코드를 실행하기 전에 선언을 먼저 훑습니다. 그래서 함수 선언문은 아래에 적어도 위에서 부를 수 있습니다(2.2). 이것을 호이스팅(hoisting) 이라고 합니다.
let 과 const 도 훑기는
하지만, 선언한 줄에 닿기 전에는 읽을 수 없습니다.
console.log("시작"); console.log(later); let later = 1;
"없는 이름" 이 아니라 "아직 쓸 수 없는 이름" 이라고 알려 줍니다. 이 구분이
var 보다 나은 점입니다 —
var 는 같은 자리에서 조용히
undefined 를 냅니다.
처음에 자주 걸리는 것
안에서 만든 것은 밖에서 보이지 않습니다. 밖에서 쓰려면
return 으로 돌려줘야 합니다(2.1).
ReferenceError: result is not defined
for (let i = ...) 의
i 는 반복문 안에서만 보입니다(1.10).
let 없이 count = 1 만
적으면 어디에서도 보이는 변수가 만들어집니다. 실수로 다른 곳의 값을 덮어쓰게
되므로 언제나 let 이나
const 를 적으세요.
직접 해보기
아래 코드의 출력을 먼저 적어 보고, 편집기에 넣어 확인하세요.
let 이 없습니다. 새로 만드는 것이 아니라 바깥 것을 바꾸는 것입니다.
아래 함수는 var 때문에
temp 가 조건 밖에서도 보입니다.
let 으로 고치고, 그래도 동작하도록 자리를
옮기세요.
이 단원의 정리
- 중괄호 안에서 선언한 것은 그 안에서만 보입니다.
- 안쪽에서는 바깥이 보이고, 바깥에서는 안쪽이 보이지 않습니다.
- 이름이 같으면 가까운 것이 보입니다.
var는 중괄호를 스코프로 보지 않아 값이 새어 나갑니다. 사용하지 않습니다.- 함수 선언문은 위에서 부를 수 있지만,
let·const는 선언한 줄에 닿아야 읽을 수 있습니다.