ES2015+ 핵심 문법 (ES6 and Beyond)
한눈에 보기
ES2015는 let과 const, 화살표 함수, 클래스, 프로미스, 모듈 등 현대 JavaScript의 근간을 도입한 표준이다. 이후 async/await와 옵셔널 체이닝까지 이어지는 핵심 문법을 정리한다.
최종 업데이트 2026.09.17
ES2015(ES6)는 2015년에 확정된 ECMAScript 표준으로, let과 const, 화살표 함수(Arrow Function), 클래스(Class), 템플릿 리터럴, 구조 분해 할당, 프로미스(Promise), 모듈(Module) 등 현대 JavaScript의 근간이 되는 문법을 한꺼번에 도입한 대규모 개정판이다. 이후 ECMAScript는 매년 새 판을 발표하는 체제로 바뀌었고, async와 await, 옵셔널 체이닝 같은 기능이 순차적으로 추가되어 오늘날의 JavaScript를 이루고 있다.
let, const와 블록 스코프
ES2015 이전의 var는 함수 스코프만 가지며, 선언 전에 접근해도 undefined가 나오는 호이스팅(Hoisting) 동작 때문에 버그의 원인이 되곤 했다. let과 const는 블록 스코프를 가지며, 선언 전에 접근하면 일시적 사각지대(Temporal Dead Zone) 때문에 참조 오류가 발생하므로 실수를 조기에 드러낸다. const는 재할당을 금지할 뿐 객체 내부의 변경까지 막지는 않는다는 점에 주의해야 한다.
| 구분 | var | let | const |
|---|---|---|---|
| 스코프 | 함수 스코프 | 블록 스코프 | 블록 스코프 |
| 재선언 | 허용 | 불가 | 불가 |
| 재할당 | 허용 | 허용 | 불가 |
| 선언 전 접근 | undefined 반환 | 참조 오류 | 참조 오류 |
화살표 함수와 this
화살표 함수는 function 키워드보다 간결할 뿐 아니라 this 바인딩 규칙이 다르다. 일반 함수의 this는 호출 방식에 따라 동적으로 결정되지만, 화살표 함수는 자신만의 this를 만들지 않고 선언된 위치의 상위 스코프 this를 그대로 사용한다. 그래서 콜백 안에서 바깥의 this를 유지하고 싶을 때 유용하다. 반대로 자신만의 this가 필요한 객체의 메서드나 생성자로는 적합하지 않으며, arguments 객체도 갖지 않는다.
class Timer {
constructor() {
this.seconds = 0;
setInterval(() => {
this.seconds += 1; // 상위 스코프의 this를 그대로 사용
}, 1000);
}
}
구조 분해, 스프레드, 템플릿 리터럴
구조 분해 할당(Destructuring Assignment)은 배열이나 객체에서 필요한 값을 변수로 바로 꺼내는 문법이고, 스프레드(Spread) 문법은 반복 가능한 값을 펼쳐서 복사하거나 합치는 문법이다. 템플릿 리터럴(Template Literal)은 백틱으로 감싼 문자열 안에 표현식을 삽입하고 여러 줄 문자열을 쉽게 만들 수 있게 한다. 세 가지 모두 실무 코드의 가독성을 크게 끌어올렸다.
const user = { name: "민수", age: 27, city: "서울" };
const { name, age = 20 } = user; // 객체 구조 분해와 기본값
const [first, ...rest] = [1, 2, 3]; // 배열 구조 분해와 나머지
const copied = { ...user, age: 28 }; // 얕은 복사 후 일부 갱신
const greeting = `안녕하세요, ${name}님`; // 템플릿 리터럴
스프레드로 만드는 복사는 얕은 복사(Shallow Copy)라서 중첩 객체는 여전히 참조를 공유한다는 점을 기억해야 한다.
클래스와 모듈
class 문법은 생성자 함수와 프로토타입 기반 상속을 읽기 쉬운 형태로 감싼 문법적 설탕(Syntactic Sugar)이다. constructor, extends, super, 정적 메서드를 지원하며, ES2022부터는 #을 붙인 비공개 필드(Private Field)도 표준이 되었다. 모듈 시스템은 import와 export 키워드로 파일 단위의 스코프를 제공하여, 전역 오염 없이 코드를 분리하고 재사용할 수 있게 한다. CommonJS의 require와 달리 ES 모듈은 정적 구조라서 빌드 도구가 사용하지 않는 코드를 제거하는 트리 셰이킹(Tree Shaking)에 유리하다.
비동기 처리의 진화
ES2015의 프로미스는 콜백 중첩으로 인한 콜백 지옥(Callback Hell)을 then 체인으로 평탄화했고, ES2017의 async와 await는 비동기 코드를 동기 코드처럼 위에서 아래로 읽히게 만들었다. async 함수는 항상 프로미스를 반환하며, await는 프로미스가 처리될 때까지 함수 실행을 일시 중단한다. 오류 처리는 try와 catch로 통일된다.
async function loadUser(id) {
try {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error("요청 실패");
return await res.json();
} catch (err) {
console.error(err);
return null;
}
}
ES2016 이후의 주요 추가 기능으로는 지수 연산자 **(ES2016), Object.entries(ES2017), 옵셔널 체이닝 ?.과 널 병합 연산자 ??(ES2020), 배열의 at 메서드(ES2022), 원본을 바꾸지 않는 toSorted와 toReversed(ES2023) 등이 있다. 매년 작은 단위로 발전하므로 연도별 명세보다 기능 단위로 익히는 편이 실용적이다.
면접에서 이렇게 물어본다
- var, let, const의 차이를 스코프와 호이스팅, 일시적 사각지대 개념으로 설명해 보라.
- 화살표 함수와 일반 함수의 this 바인딩 차이는 무엇이며, 화살표 함수를 쓰면 안 되는 경우는 언제인가.
- 프로미스와 async, await의 관계를 설명하고 콜백 지옥을 어떻게 해결하는지 말해 보라.
- 스프레드 문법으로 객체를 복사할 때 생기는 얕은 복사의 한계를 예로 들어 보라.
- ES 모듈과 CommonJS 모듈의 차이, 그리고 트리 셰이킹과의 관계를 설명해 보라.
JavaScript / Python에서 같이 읽기
- 클로저 (Closure)클로저는 함수가 선언된 시점의 렉시컬 환경을 기억해 스코프 밖에서도 변수에 접근하게 하는 JavaScript 특성이다. 동작 원리, 카운터 예시, 데이터 은닉 활용, var와 let의 루프 함정까지 정리한다.
- JavaScript 데이터 타입 (Data Types)JavaScript 데이터 타입은 원시 타입 7가지와 객체 타입으로 나뉜다. 값 복사와 참조 복사의 차이, typeof의 함정, 암묵적 타입 변환과 ===, Truthy와 Falsy까지 핵심을 정리한다.
- 객체와 프로토타입 (Object and Prototype)JavaScript의 모든 객체는 프로토타입을 내부 링크로 참조하며, 프로토타입 체인을 따라 프로퍼티를 탐색해 상속을 구현한다. prototype과 __proto__의 구분, class 문법, 프로토타입 오염까지 다룬다.
- 파이썬 자동화 라이브러리 (Python Automation)파이썬 자동화 라이브러리는 마우스와 키보드 입력, 화면 인식, 브라우저 조작을 코드로 수행하는 도구다. PyAutoGUI, Selenium, pywinauto의 접근 방식 차이와 선택 기준, 주의점을 정리한다.
이 개념, 내 코드에서는 어떻게 물어볼까요
데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.
공고 넣고 시작하기