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는 재할당을 금지할 뿐 객체 내부의 변경까지 막지는 않는다는 점에 주의해야 한다.

구분varletconst
스코프함수 스코프블록 스코프블록 스코프
재선언허용불가불가
재할당허용허용불가
선언 전 접근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 문서 전체 보기

이 개념, 내 코드에서는 어떻게 물어볼까요

데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.

공고 넣고 시작하기