JS LAB
JS 2.4 · 2부. 함수와 스코프

스코프와 호이스팅

변수가 보이는 범위를 알아보고, var 를 사용하지 않는 이유를 봅니다.

예상 학습 시간 15분 실행 단추가 있는 예제는 고쳐서 실행해 볼 수 있습니다 난이도 초급
개념 설명

변수가 보이는 범위

변수는 아무 데서나 보이지 않습니다. 선언한 자리에 따라 보이는 범위가 정해지는데, 그 범위를 스코프(scope) 라고 합니다.

규칙은 하나입니다. 중괄호 안에서 선언한 것은 그 중괄호 안에서만 보입니다. 안쪽에서는 바깥을 볼 수 있지만, 바깥에서는 안쪽을 볼 수 없습니다.

최소 예제 · 편집 가능

같은 이름, 다른 자리

script.js
const name = "바깥";

function show() {
	const name = "안쪽";
	console.log(name);
}

show();
console.log(name);
출력
안쪽 바깥

이름이 같아도 서로 다른 변수입니다. 함수 안에서는 가까운 것이 보입니다.

상세 사용법

안쪽에서는 바깥이 보입니다

script.js
const tax = 0.1;

function withTax(price) {
	return price + price * tax;
}

console.log(withTax(10000));
출력
11000

tax 는 함수 밖에 있지만 안에서 보입니다. 이렇게 여러 함수가 함께 쓰는 값은 밖에 한 번만 두는 편이 낫습니다.

상세 사용법

중괄호면 모두 스코프입니다

함수뿐 아니라 iffor 의 중괄호도 스코프를 만듭니다.

script.js
if (true) {
	let inside = "블록 안";
	console.log(inside);
}

console.log(typeof inside);
출력
블록 안 undefined

밖에서는 inside 가 없습니다. 그대로 읽으면 오류가 나므로 typeof 로 확인했습니다 — typeof 는 없는 이름에도 오류를 내지 않습니다.

상세 사용법

var 를 사용하지 않는 이유

varlet 이 생기기 전에 쓰던 것입니다. 중괄호를 스코프로 보지 않습니다.

script.js
function withVar() {
	if (true) {
		var x = "var 는 블록을 넘습니다";
	}
	console.log(x);
}

withVar();
출력
var 는 블록을 넘습니다

if 안에서 선언했는데 밖에서 읽힙니다. 반복문 안에서 만든 변수가 밖으로 새어 나가는 일이 생겨 찾기 어려운 버그가 됩니다. 새 코드에는 var 를 사용하지 않습니다.

상세 사용법

호이스팅

JavaScript 는 코드를 실행하기 전에 선언을 먼저 훑습니다. 그래서 함수 선언문은 아래에 적어도 위에서 부를 수 있습니다(2.2). 이것을 호이스팅(hoisting) 이라고 합니다.

letconst 도 훑기는 하지만, 선언한 줄에 닿기 전에는 읽을 수 없습니다.

script.js
console.log("시작");
console.log(later);

let later = 1;
출력 · 크롬
시작 ReferenceError: Cannot access 'later' before initialization
출력 · 파이어폭스
시작 ReferenceError: can't access lexical declaration 'later' before initialization

"없는 이름" 이 아니라 "아직 쓸 수 없는 이름" 이라고 알려 줍니다. 이 구분이 var 보다 나은 점입니다 — var 는 같은 자리에서 조용히 undefined 를 냅니다.

흔한 실수

처음에 자주 걸리는 것

1. 함수 안에서 만든 값을 밖에서 읽습니다

안에서 만든 것은 밖에서 보이지 않습니다. 밖에서 쓰려면 return 으로 돌려줘야 합니다(2.1).

ReferenceError: result is not defined
2. 반복문의 변수를 밖에서 읽습니다

for (let i = ...)i 는 반복문 안에서만 보입니다(1.10).

3. 선언 없이 값을 넣습니다

let 없이 count = 1 만 적으면 어디에서도 보이는 변수가 만들어집니다. 실수로 다른 곳의 값을 덮어쓰게 되므로 언제나 let 이나 const 를 적으세요.

실습 문제

직접 해보기

1. 무엇이 출력될까요 난이도 하

아래 코드의 출력을 먼저 적어 보고, 편집기에 넣어 확인하세요.

let value = "바깥"; function change() { value = "바뀜"; } change(); console.log(value);
함수 안에 let 이 없습니다. 새로 만드는 것이 아니라 바깥 것을 바꾸는 것입니다.
바뀜
2. 새어 나가지 않게 고치기 난이도 중

아래 함수는 var 때문에 temp 가 조건 밖에서도 보입니다. let 으로 고치고, 그래도 동작하도록 자리를 옮기세요.

function pick(score) { if (score >= 60) { var temp = "합격"; } else { var temp = "불합격"; } return temp; }
function pick(score) { let temp; if (score >= 60) { temp = "합격"; } else { temp = "불합격"; } return temp; } console.log(pick(80));
요약

이 단원의 정리

  • 중괄호 안에서 선언한 것은 그 안에서만 보입니다.
  • 안쪽에서는 바깥이 보이고, 바깥에서는 안쪽이 보이지 않습니다.
  • 이름이 같으면 가까운 것이 보입니다.
  • var 는 중괄호를 스코프로 보지 않아 값이 새어 나갑니다. 사용하지 않습니다.
  • 함수 선언문은 위에서 부를 수 있지만, let · const 는 선언한 줄에 닿아야 읽을 수 있습니다.