자바스크립트 예약어는 처음 배우는 사람을 가장 먼저 당황하게 만드는 벽이다. 변수 이름을 class나 new로 지었더니 에디터가 빨간 줄을 긋거나, 실행하자마자 SyntaxError가 뜬다. 이게 바로 예약어 때문이다. 이 글에서는 자바스크립트 예약어와 키워드가 어떻게 다른지, 그리고 strict 모드와 최신 ES 버전에서 달라지는 부분까지 2026년 기준으로 한 번에 정리한다.

키워드와 예약어, 뭐가 다른가
둘 다 “변수나 함수 이름으로 못 쓰는 단어”라는 점은 같다. 그런데 성격이 다르다.
키워드는 언어가 이미 쓰고 있는 단어다. if, for, return처럼 문법의 한 부분으로 동작한다. 제어문의 시작과 끝을 표시하거나, 특정 동작을 지시하는 기능이 이미 키워드에 묶여 있다. 그래서 식별자나 프로퍼티 이름으로 쓰면 엔진이 헷갈린다. 못 쓰게 막는 이유다.
예약어는 지금은 비어 있지만 미래를 위해 자리를 잡아둔 단어다. 당장은 하는 일이 없어도, 나중에 키워드로 승격될 가능성이 있어서 미리 막아둔다. 옛날에 let이 예약어였다가 ES6에서 진짜 변수 선언 키워드가 된 게 대표적인 예다. 미리 막아두지 않았다면, let을 변수 이름으로 쓰던 코드가 새 문법이 나오는 순간 전부 깨졌을 거다.
식별자가 뭔지부터 헷갈린다면 자바스크립트를 위한 기초 지식을 먼저 보고 오면 흐름이 잡힌다. 식별자는 쉽게 말해 우리가 직접 짓는 이름이다. 변수, 함수, 클래스에 붙이는 이름 전부가 식별자다.
키워드: 언어가 이미 쓰고 있는 단어
가장 자주 마주치는 키워드부터 보자. 제어 흐름과 기본 동작을 담당하는 단어들이다.
break
case
catch
class
const
continue
debugger
default
delete
do
else
export
extends
false
finally
for
function
if
import
in
instanceof
new
null
return
super
switch
this
throw
true
try
typeof
var
void
while
with
여기에 true, false, null처럼 값 자체를 나타내는 단어도 포함된다. 엄밀히는 리터럴이지만, 변수 이름으로 못 쓴다는 점에서 묶어서 기억하는 게 편하다. 이 목록은 자바스크립트가 발전하면서 class, const, import, export 같은 ES6 단어가 더해졌다. 모듈과 클래스 문법이 표준에 들어오면서 자연스럽게 늘어난 것이다. 이 흐름이 궁금하면 한방에 끝내는 ES6 기초에서 더 자세히 다룬다.
자바스크립트 예약어: 미래를 위해 비워둔 자리
예약어는 시대에 따라 꽤 많이 바뀌었다. 초창기 자바스크립트는 자바를 닮으려던 흔적으로 abstract, boolean, byte, char, double, float, int, long, short 같은 자료형 단어까지 예약어로 막아뒀다. 지금 기준으로는 대부분 풀렸다. 자바스크립트가 자바와 다른 길을 가면서 더 이상 필요 없어졌기 때문이다.
2026년 현재 기준으로 정리하면 훨씬 단순하다. 어디서든 예약된 미래 예약어는 사실상 enum 하나만 남았다. 나머지는 사용하는 위치, 즉 모드에 따라 달라진다. 이 변화 흐름은 지난 3년간의 자바스크립트 및 타입스크립트의 모든 기능 리뷰에서도 확인할 수 있다.
strict 모드에서 달라지는 예약어
ES5부터 자바스크립트에 strict 모드(엄격 모드)가 생겼다. 파일이나 함수 맨 위에 'use strict'를 적으면 켜진다. 모듈과 클래스 내부는 기본으로 strict 모드다. 이 모드에서는 일반 모드에서 멀쩡히 쓰던 단어 몇 개가 추가로 막힌다.
implements
interface
let
package
private
protected
public
static
yield
그래서 똑같은 이름인데 일반 스크립트에서는 되고 모듈 안에서는 에러가 나는 일이 생긴다. 헷갈린다면 규칙은 간단하다. 요즘 코드는 거의 다 모듈이고 strict 모드다. 그러니 이 단어들도 그냥 쓰지 않는 게 안전하다.
컨텍스트 예약어: 위치에 따라 달라진다
여기가 입문자가 가장 많이 헷갈리는 부분이다. 어떤 단어는 전역에서는 멀쩡한 이름인데, 특정 위치에서만 예약어처럼 동작한다. 이걸 컨텍스트 예약어라고 부른다.
await는async함수 안에서만 예약된다. 일반 함수에서는 변수 이름으로 쓸 수 있다.yield는 제너레이터 함수(function*) 안에서만 예약된다.let은 strict 모드와let/const선언 맥락에서 예약된다.async,of,as,from,get,set은 정식 예약어가 아니다. 특정 문법에서 역할을 하지만, 변수 이름으로도 쓸 수 있다.
정리하면, async는 어디서나 변수 이름으로 쓸 수 있지만 await는 비동기 함수 안에서 막힌다. 이름만 보면 비슷한데 규칙이 다른 셈이다. 비동기 문법이 낯설다면 이 차이가 더 와닿을 거다. 더 깊이 보고 싶으면 공식 문서인 MDN 어휘 문법(Lexical grammar)이 가장 정확하다.
예약어를 변수로 쓰면 실제로 무슨 일이 생기나
말로만 보면 와닿지 않으니 코드로 확인해 보자. 키워드를 변수 이름으로 쓰면 코드가 실행되기도 전에 막힌다.
// SyntaxError: Unexpected token 'class'
let class = "초급반";
// SyntaxError: Unexpected token 'new'
const new = {};
엔진이 class를 보는 순간 “아, 클래스 선언이 시작되는구나” 하고 기대했다가, 뒤에 등호가 나오니 문법이 깨졌다고 판단한다. 그래서 런타임 에러가 아니라 파싱 단계의 SyntaxError가 난다. 코드가 한 줄도 돌지 않는다는 뜻이다.
컨텍스트 예약어는 더 헷갈린다. 같은 단어인데 위치에 따라 결과가 갈린다.
// 일반 함수에서는 멀쩡하다
function normal() {
let await = 1; // OK
return await;
}
// async 함수에서는 막힌다
async function run() {
let await = 1; // SyntaxError
}
이런 차이를 미리 알아두면, 알 수 없는 에러로 한참 헤매는 시간을 줄일 수 있다. 결국 예약어를 외우는 것보다 “왜 막히는지”를 이해하는 쪽이 오래 남는다.
실무에서 헷갈리지 않는 법
목록을 다 외울 필요는 없다. 사실 외워도 금방 잊는다. 대신 습관 몇 개만 들이면 예약어 때문에 막히는 일은 거의 사라진다.
- 의미 있는 이름을 쓴다.
class대신userClass,new대신newItem처럼 구체적으로 적으면 예약어와 겹칠 일이 없다. - 한 글자 변수를 피한다. 짧은 이름일수록 예약어와 부딪힐 확률이 높다.
- 에디터를 믿는다. VS Code 같은 도구는 예약어를 색으로 구분해준다. 변수 이름이 키워드 색으로 변하면 바로 알아챌 수 있다.
'use strict'환경을 기본으로 가정한다. 모듈로 개발하면 어차피 strict 모드다.
| 구분 | 설명 | 예시 |
|---|---|---|
|
키워드
|
이미 문법에 쓰이는 단어
|
if, for, return, class
|
|
미래 예약어
|
미래를 위해 비워둔 자리
|
enum
|
|
strict 모드 예약어
|
엄격 모드에서만 막힘
|
let, static, yield, public
|
|
컨텍스트 예약어
|
특정 위치에서만 막힘
|
await, yield
|
개발 환경을 막 세팅했다면 Node.js 설치 및 NPM 사용 가이드와 함께 보면 자바스크립트 기초를 잡는 데 도움이 된다.
정리
자바스크립트 예약어는 결국 “언어가 먼저 찜해둔 단어”다. 키워드는 지금 쓰는 단어, 예약어는 미래에 쓸지 모를 단어다. 여기에 strict 모드와 컨텍스트라는 변수가 더해져 조금 복잡해 보일 뿐이다. 핵심은 단순하다. 짧고 모호한 이름 대신 의미가 분명한 이름을 쓰면, 이 목록을 외우지 않아도 에러를 만날 일이 없다. 오늘 작성하던 변수 이름 하나를 다시 들여다보자. 혹시 언어가 먼저 찜해둔 단어를 쓰고 있지는 않은가?
참고 자료
- MDN Web Docs, “Lexical grammar”
- W3Schools, “JavaScript Reserved Words”