본문 바로가기

비개발자의 개발 일지

현장 팀장에서 수출 ERP까지 — AI와 함께 시스템을 만든 기록

시리즈 보기
php

JavaScript 변수 선언 — let · 전역/지역/블록 스코프 완전 정리

by 왕진 2026. 7. 2.
반응형

 

 

Web Development · JavaScript

JavaScript 변수 선언 —
전역·지역·블록 스코프 완전 정리

let 하나로 갈리는 변수의 운명 — 어디서 만들었느냐가 어디서 쓸 수 있는지를 정한다
시작 오늘 분석할 코드

변수 하나(x)는 어디서든 쓸 수 있는데, 다른 변수(y, b)는 특정 구간을 벗어나면 존재 자체가 사라진다. 그리고 실수로 let을 빼먹은 변수(z)는 원래 의도와 다르게 동작한다. 이 세 가지 현상을 한 코드 안에서 확인해본다.

<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>변수 선언</title> </head> <body> <h3>변수 선언, 전역/지역/블록 변수</h3> <hr> <script> let x; // 전역 변수 x 선언. var로 선언해도 동일 function f() { let y; // 함수 f() 내에서만 사용되는 지역 변수 y 선언. var로 선언해도 동일 x = 10; // 전역 변수 x에 10 저장 y = 20; // 지역 변수 y에 20 저장 z = 30; // 새로운 전역 변수 z가 선언되고 30이 저장됨 if(y == 20) { let b = 40; // if 블록에서만 사용되는 블록 변수 b 선언 b++; document.write("if 블록 내 블록변수 b = " + b + "<br>"); } // 이곳에서는 블록 변수 b에 접근할 수 없음 // 이곳에서는 변수 x, y, z에 모두 접근 가능 document.write("함수 f() 내 지역변수 y = " + y + "<br>"); } f(); // 함수 f() 호출 document.write("전역변수 x = " + x + "<br>"); document.write("전역변수 z = " + z); // 이곳에서는 변수 x와 z만 접근 가능, 지역 변수 y와 블록 변수 b는 접근 불가 </script> </body> </html>
실제 출력 미리보기

변수 선언, 전역/지역/블록 변수


if 블록 내 블록변수 b = 41
함수 f() 내 지역변수 y = 20
전역변수 x = 10
전역변수 z = 30
※ 순서를 눈여겨보자. f()가 호출되는 그 순간, 함수 안의 if 블록이 먼저 실행되며 "b = 41"을 출력하고, 그다음 함수 안 나머지 코드가 "y = 20"을 출력한다. 함수가 끝난 뒤에야 바깥 코드가 "x = 10", "z = 30"을 출력한다. 코드는 위에서 아래로 실행되는 게 아니라 호출된 순서대로 실행된다.
용어 용어 정리
변수값을 담아두는 이름표 붙은 상자
letES6부터 쓰는 변수 선언 키워드, 스코프가 명확함
var옛날 방식 변수 선언 키워드, 블록 스코프가 없음
스코프변수가 "살아있고 접근 가능한" 범위
전역변수코드 어디서든 접근 가능한 변수
지역변수함수 안에서 선언되어 그 함수 안에서만 접근 가능
블록변수중괄호 {} 블록 안에서만 접근 가능
스코프 체인안쪽 블록이 바깥쪽 변수를 거슬러 올라가며 찾는 구조

1 변수란 무엇이고 왜 "어디서 선언했는지"가 중요한가
변수는 이름표가 붙은 저장 공간이다

변수는 값을 담아두고 나중에 그 이름으로 다시 꺼내 쓰기 위한 저장 공간이다. 그런데 이 상자를 아무 데서나 만들 수 있는 게 아니라, 어느 위치에서 만들었는지에 따라 그 상자를 열어볼 수 있는 범위가 달라진다. 이 범위를 스코프(scope, 유효범위)라고 부른다.

왜 이런 규칙이 필요할까? 만약 모든 변수가 어디서든 접근 가능하다면, 큰 프로그램에서는 변수 이름이 서로 충돌하고, 함수 하나를 고치다가 전혀 상관없는 다른 코드가 망가지는 일이 생긴다. 스코프는 "이 변수는 여기까지만 책임진다"는 경계선을 그어서 코드를 안전하게 나누는 장치다.

※ 실생활 비유: 회사 전체가 쓰는 공용 문서함(전역변수)과 내 팀만 쓰는 캐비닛(지역변수), 그리고 지금 진행 중인 회의실에서만 쓰는 화이트보드(블록변수)를 떠올리면 된다. 회의가 끝나면 화이트보드 내용은 지워진다.

2 let로 변수 선언하기
let x; 는 무엇을 하는 코드인가

let x;는 "x라는 이름의 변수 상자를 만들겠다"는 선언이다. 아직 값은 안 들어있고(undefined), 나중에 x = 10;처럼 대입해서 값을 채운다. 선언과 대입을 한 줄로 합쳐 let x = 10;처럼 쓸 수도 있다.

원본 코드의 주석에 "var로 선언해도 동일"이라고 적혀 있는데, 값을 저장하고 꺼내 쓰는 기본 동작은 let이나 var나 똑같다. 차이는 뒤에서 다룰 블록 스코프를 지키느냐 아니냐에 있다.

let x; // 선언만, 값은 아직 undefined x = 10; // 대입, 이제 x는 10 let y = 20; // 선언 + 대입을 한 줄에

3 전역변수 — 코드 어디서든 접근 가능
x는 왜 함수 밖에서도 보이는가

변수 x<script> 태그 최상단, 즉 어떤 함수 안에도 속하지 않은 위치에서 let x;로 선언됐다. 함수 밖(전역)에서 선언된 변수는 코드 전체에서 접근 가능한 전역변수가 된다.

그래서 함수 f() 안에서 x = 10;으로 값을 넣어도, 함수가 끝난 뒤 바깥의 document.write("전역변수 x = " + x + "<br>")에서 그 값 10을 그대로 읽을 수 있다. 같은 상자를 안에서도 밖에서도 공유하는 것이다.

※ 전역변수는 편리하지만 남용하면 위험하다. 코드 어디서나 값을 바꿀 수 있다는 말은, 코드 어디선가 실수로 값을 바꿔도 원인을 찾기 어렵다는 뜻이기도 하다.

 

반응형

 

4 지역변수 — 함수 안에서만 유효
y는 왜 함수 밖에서 접근할 수 없는가

변수 yfunction f() { ... }의 중괄호 안쪽에서 let y;로 선언됐다. 함수 안에서 선언된 변수는 그 함수가 실행되는 동안에만 존재하는 지역변수가 되고, 함수가 끝나면 사라진다.

그래서 마지막 줄에서 document.write("전역변수 z = " + z) 다음에 만약 y를 출력하려 하면 "y is not defined" 에러가 난다. y라는 상자 자체가 함수 f()의 실행이 끝나는 순간 치워지기 때문이다.

※ 원본 코드 마지막 줄 주석에도 정확히 이렇게 적혀 있다 — "지역 변수 y와 블록 변수 b는 접근 불가". 이는 버그가 아니라 스코프가 정상적으로 동작하는 증거다.

5 블록변수 — if·for의 중괄호 안에서만 유효
b는 왜 if 블록을 나가면 사라지는가

변수 b는 함수 f() 안이 아니라, 그보다 한 단계 더 안쪽인 if(y == 20) { ... }의 중괄호 안에서 let b = 40;으로 선언됐다. let은 함수 단위가 아니라 중괄호 {} 블록 단위로 스코프를 만들기 때문에, b는 이 if 블록을 벗어나는 순간 존재하지 않게 된다.

그래서 원본 코드 주석처럼 if 블록이 끝난 직후 줄에서도 b에는 접근할 수 없다. b++;로 41이 된 값은 블록 안에서 출력(document.write)하는 그 순간에만 쓸 수 있고, 블록을 나가면 상자째로 사라진다.

중첩된 스코프를 상자 그림으로 보면

전역 · 함수 · 블록은 서로 독립된 것이 아니라, 바깥 상자 안에 안쪽 상자가 들어있는 구조다. 안쪽 상자에서는 바깥 상자의 내용물을 꺼내볼 수 있지만, 바깥에서는 안쪽 상자를 열 수 없다.

전역 스코프 — 접근 가능: x, z
함수 f() 지역 스코프 — 접근 가능: x, y, z (전역까지 포함)
if 블록 스코프 — 접근 가능: x, y, z, b (바깥 전부 포함)
※ 안쪽 상자에서 바깥 상자 물건을 꺼내 쓸 수는 있어도(위에서 아래로 화살표), 바깥 상자에서 안쪽 상자 물건은 못 꺼낸다(아래에서 위로는 화살표 없음). 이게 스코프의 "한쪽 방향" 규칙이다.

6 스코프 체인 — 변수를 찾는 순서
if 블록 안에서 y == 20을 비교할 수 있는 이유

if 블록 안 조건식 if(y == 20)은 블록 바깥쪽인 함수 스코프에 있는 y를 참조한다. 자바스크립트는 변수를 찾을 때 가장 가까운 안쪽 스코프부터 시작해서, 없으면 한 단계씩 바깥으로 나가며 찾는다. 이 탐색 경로를 스코프 체인(scope chain)이라 부른다.

if 블록에서 y 찾기
여기 없음, 한 단계 바깥으로
함수 f() 스코프에서 y 발견 (20)

반대로 함수 스코프에서 b를 찾으려 하면, 함수 스코프에는 없고 더 바깥인 전역 스코프로도 찾아 나가지만 거기에도 없으므로 "정의되지 않음" 에러가 난다. 스코프 체인은 안에서 밖으로만 뻗어나가지, 밖에서 안으로 내려가는 경로는 애초에 없다.


7 let 없이 대입하면 전역변수가 되는 함정
z = 30; 인데 왜 전역변수가 되는가

함수 f() 안의 z = 30;을 잘 보면 let이나 var 없이 그냥 대입만 하고 있다. 이렇게 선언 키워드 없이 값을 대입하면, 자바스크립트는 자동으로 전역 스코프에 새 변수를 만들어버린다. 함수 안에서 썼다고 해서 지역변수가 되는 게 아니다.

그래서 함수가 끝난 뒤 바깥의 document.write("전역변수 z = " + z)에서 z가 문제없이 30을 출력한다. 코드를 짠 사람이 "z도 y처럼 함수 안에서만 쓰는 변수겠지"라고 생각했다면, 이건 의도와 다르게 동작하는 함정이다.

※ 이 동작은 버그가 아니라 자바스크립트의 정식 규칙(암묵적 전역, implicit global)이지만, 실무에서는 거의 항상 실수의 원인이 된다. 함수 안에서 쓰는 모든 변수는 반드시 let(또는 const)으로 선언하는 습관이 중요하다.

8 var와 let, 무엇이 다른가
둘 다 변수를 선언하는데 왜 let을 더 권장하는가

원본 코드 주석은 "var로 선언해도 동일"이라고 하지만, 이는 전역·지역 스코프 동작에 한해서다. iffor 같은 블록 스코프에서는 둘의 동작이 갈린다.

let (ES6+)
중괄호 {} 블록 단위로 스코프 생성
if 블록 안 let b는 블록 밖에서 완전히 사라짐
같은 이름 재선언 시 에러 발생 → 실수를 바로 알 수 있음
var (구식)
함수 단위로만 스코프 생성, 블록은 무시
if 블록 안 var b는 블록 밖에서도 접근 가능(!)
같은 이름 재선언해도 에러 없이 덮어씀 → 실수를 못 알아챔
if (true) { var b = 40; } console.log(b); // var는 40 출력 (블록 무시하고 새어나옴) if (true) { let b = 40; } console.log(b); // let은 에러 (b is not defined, 블록 안에 갇힘)
※ 그래서 요즘은 왜 let·const를 쓰는가
  • 블록 스코프가 명확해서 변수가 "새어나가는" 사고를 막는다
  • 재선언 시 에러를 내서 오타·중복 실수를 코드 작성 시점에 잡아준다
  • 값이 안 바뀌는 변수는 const로 선언해 더 안전하게 쓸 수 있다

9 자주 하는 실수
실수 증상 해결
함수 안에서 let 없이 변수 = 값만 씀 지역변수인 줄 알았는데 전역변수가 되어버림 모든 변수는 let·const로 반드시 선언 후 사용
if·for 블록 밖에서 블록변수 접근 "변수명 is not defined" 에러 블록 밖에서도 필요한 값이면 블록 바로 위에서 변수 선언
함수 안팎에서 같은 이름을 지역·전역에 중복 사용 어느 값을 참조하는지 헷갈려 디버깅 지연 스코프가 다르면 이름도 다르게 지어 혼동 방지
var로 블록 스코프를 기대하고 코딩 블록 안 변수가 밖으로 새어나가 값이 덮어써짐 블록 스코프가 필요하면 무조건 let·const 사용
함수가 끝난 뒤 지역변수를 바깥에서 다시 참조 시도 "is not defined" 에러 또는 undefined 함수 실행 결과가 필요하면 return으로 값을 반환받아 사용

핵심 한 줄 요약

전역변수함수 밖에서 선언 → 코드 어디서든 접근 가능
지역변수함수 안에서 선언 → 그 함수 안에서만 접근, 끝나면 사라짐
블록변수if·for의 {} 안에서 선언 → 그 블록을 벗어나면 사라짐
스코프 체인안쪽에서 바깥쪽으로만 변수를 찾아 나감, 반대는 불가
let 없이 대입의도와 달리 전역변수가 생기는 함정 (암묵적 전역)
let vs varlet은 블록 스코프를 지킴, var는 블록을 무시하고 새어나감

Tags

#JavaScript #변수선언 #let #var #스코프 #전역변수 #지역변수 #블록변수 #유효범위 #스코프체인 #자바스크립트기초 #JS #웹개발 #티스토리
▼ 티스토리 태그 입력란 복사용
JavaScript, 변수선언, let, var, 스코프, 전역변수, 지역변수, 블록변수, 유효범위, 스코프체인, 자바스크립트기초, JS, 웹개발, 티스토리
반응형

댓글