← 가이드 목록으로 ← Back to guides

JavaScript ES6+ 핵심 문법과 현대적 패턴 완벽 정리 JavaScript ES6+ Core Syntax and Modern Patterns Complete Guide

2015년 ES6(ECMAScript 2015)의 등장으로 JavaScript는 완전히 새로운 언어가 되었습니다. 화살표 함수, 클래스, 모듈, async/await... 이 모든 것이 ES6 이후에 추가된 기능입니다.

With the introduction of ES6 (ECMAScript 2015), JavaScript became a completely new language. Arrow functions, classes, modules, async/await... all of these were added after ES6.

이 가이드에서는 현대 JavaScript 개발에서 반드시 알아야 할 핵심 문법왜 이런 형태가 표준이 되었는지를 설명합니다.

This guide explains the essential syntax you must know for modern JavaScript development and why these patterns became standard.

let, const: 블록 스코프 변수 선언 let, const: Block-Scoped Variable Declarations

ES6 이전에는 var만 있었는데, 함수 스코프와 호이스팅으로 인해 많은 버그가 발생했습니다. letconst는 이 문제를 해결합니다.

Before ES6, only var existed, causing many bugs due to function scope and hoisting. let and const solve these problems.

❌ ES5 (var)
var x = 10;
if (true) {
  var x = 20;
}
console.log(x); // 20 😱
✅ ES6+ (let/const)
let x = 10;
if (true) {
  let x = 20;
}
console.log(x); // 10 ✓

💡 let vs const 사용 원칙 💡 let vs const Usage Principle

기본적으로 const를 사용하고, 재할당이 필요한 경우에만 let을 사용하세요.

이렇게 하면 코드를 읽는 사람이 "이 변수는 바뀔 수 있구나"를 명확히 알 수 있습니다.

Use const by default, and only use let when reassignment is needed.

This makes it clear to readers that "this variable can change."

화살표 함수 (Arrow Function) Arrow Functions

화살표 함수는 더 짧은 문법과 this 바인딩의 변화라는 두 가지 장점을 제공합니다.

Arrow functions provide two advantages: shorter syntax and different this binding.

// 기존 함수 표현식
const add = function(a, b) {
  return a + b;
};

// 화살표 함수 (한 줄)
const add = (a, b) => a + b;

// 화살표 함수 (여러 줄)
const calculate = (a, b) => {
  const sum = a + b;
  return sum * 2;
};

// 배열 메서드와 함께 사용
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);
// Traditional function expression
const add = function(a, b) {
  return a + b;
};

// Arrow function (one line)
const add = (a, b) => a + b;

// Arrow function (multiple lines)
const calculate = (a, b) => {
  const sum = a + b;
  return sum * 2;
};

// Used with array methods
const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map(n => n * 2);
const evens = numbers.filter(n => n % 2 === 0);

💡 this 바인딩 차이 💡 this Binding Difference

화살표 함수는 자신만의 this를 가지지 않고, 외부 스코프의 this를 그대로 사용합니다. 이는 콜백 함수에서 this 관련 버그를 방지해줍니다.

Arrow functions don't have their own this; they use the this from the outer scope. This prevents this-related bugs in callbacks.

구조분해 할당 (Destructuring) Destructuring Assignment

배열이나 객체에서 값을 추출하여 변수에 할당하는 간편한 문법입니다. 코드를 훨씬 읽기 쉽게 만들어줍니다.

A convenient syntax for extracting values from arrays or objects into variables. It makes code much more readable.

// 객체 구조분해
const user = { name: 'Kim', age: 25, city: 'Seoul' };
const { name, age } = user;
console.log(name); // 'Kim'

// 다른 이름으로 할당
const { name: userName } = user;

// 기본값 설정
const { country = 'Korea' } = user;

// 배열 구조분해
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [3, 4, 5]

// 함수 매개변수에서 사용
function greet({ name, age }) {
  return `Hello, ${name}! You are ${age}`;
}
// Object destructuring
const user = { name: 'Kim', age: 25, city: 'Seoul' };
const { name, age } = user;
console.log(name); // 'Kim'

// Assign to different name
const { name: userName } = user;

// Default values
const { country = 'Korea' } = user;

// Array destructuring
const [first, second, ...rest] = [1, 2, 3, 4, 5];
console.log(first); // 1
console.log(rest); // [3, 4, 5]

// In function parameters
function greet({ name, age }) {
  return `Hello, ${name}! You are ${age}`;
}

템플릿 리터럴 (Template Literals) Template Literals

백틱(`)을 사용하여 문자열을 더 직관적으로 작성할 수 있습니다. 변수 삽입과 여러 줄 문자열을 쉽게 표현합니다.

Using backticks (`) allows more intuitive string writing. Easy variable interpolation and multi-line strings.

const name = 'World';
const age = 25;

// 기존 방식 // Traditional way
const msg1 = 'Hello, ' + name + '! Age: ' + age;

// 템플릿 리터럴 // Template literal
const msg2 = `Hello, ${name}! Age: ${age}`;

// 여러 줄 문자열 // Multi-line strings
const html = ` <div class="card"> <h2>${name}</h2> <p>Age: ${age}</p> </div> `;

// 표현식 사용 // Using expressions
const result = `Total: ${10 + 20}`;

스프레드 연산자 (...) Spread Operator (...)

배열이나 객체를 "펼쳐서" 개별 요소로 만들어줍니다. 복사, 병합, 함수 호출에 유용합니다.

"Spreads" arrays or objects into individual elements. Useful for copying, merging, and function calls.

// 배열 복사 (얕은 복사)
const arr1 = [1, 2, 3];
const arr2 = [...arr1];

// 배열 병합
const combined = [...arr1, 4, 5, ...arr2];

// 객체 복사 및 수정
const user = { name: 'Kim', age: 25 };
const updated = { ...user, age: 26 };

// 함수 인자로 전달
const numbers = [5, 2, 8, 1];
Math.max(...numbers); // 8
// Array copy (shallow)
const arr1 = [1, 2, 3];
const arr2 = [...arr1];

// Array merge
const combined = [...arr1, 4, 5, ...arr2];

// Object copy and modify
const user = { name: 'Kim', age: 25 };
const updated = { ...user, age: 26 };

// Pass as function arguments
const numbers = [5, 2, 8, 1];
Math.max(...numbers); // 8

async/await: 비동기 처리 async/await: Asynchronous Handling

Promise를 더 동기적으로 읽히게 작성할 수 있는 문법입니다. 콜백 지옥과 복잡한 Promise 체인을 해결합니다.

Syntax that makes Promises read more synchronously. Solves callback hell and complex Promise chains.

// Promise 체인 방식
fetch('/api/user')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// async/await 방식
async function getUser() {
  try {
    const response = await fetch('/api/user');
    const data = await response.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

// 여러 비동기 작업 병렬 실행
const [users, posts] = await Promise.all([
  fetch('/api/users'),
  fetch('/api/posts')
]);
// Promise chain approach
fetch('/api/user')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// async/await approach
async function getUser() {
  try {
    const response = await fetch('/api/user');
    const data = await response.json();
    console.log(data);
  } catch (err) {
    console.error(err);
  }
}

// Parallel async operations
const [users, posts] = await Promise.all([
  fetch('/api/users'),
  fetch('/api/posts')
]);

ES 모듈 (import/export) ES Modules (import/export)

모듈 시스템을 통해 코드를 파일 단위로 분리하고, 필요한 것만 가져와 사용할 수 있습니다.

The module system lets you separate code into files and import only what you need.

// utils.js - 내보내기
export const add = (a, b) => a + b;
export const PI = 3.14159;

export default function multiply(a, b) {
  return a * b;
}

// main.js - 가져오기
import multiply, { add, PI } from './utils.js';
import * as utils from './utils.js';
// utils.js - exporting
export const add = (a, b) => a + b;
export const PI = 3.14159;

export default function multiply(a, b) {
  return a * b;
}

// main.js - importing
import multiply, { add, PI } from './utils.js';
import * as utils from './utils.js';

Optional Chaining (?.) 과 Nullish Coalescing (??) Optional Chaining (?.) and Nullish Coalescing (??)

ES2020에서 추가된 기능으로, null/undefined 처리를 더 안전하게 합니다.

Added in ES2020, these make null/undefined handling safer.

const user = { profile: { name: 'Kim' } };

// Optional Chaining - 안전한 속성 접근
const city = user.profile?.address?.city;
// undefined (에러 없음)

// 메서드 호출에도 사용
user.getInfo?.();

// Nullish Coalescing - null/undefined일 때만 기본값
const value = null ?? 'default'; // 'default'
const count = 0 ?? 10; // 0 (0은 null이 아니므로)

// || 연산자와의 차이
const count2 = 0 || 10; // 10 (0은 falsy)
const user = { profile: { name: 'Kim' } };

// Optional Chaining - safe property access
const city = user.profile?.address?.city;
// undefined (no error)

// Also works with method calls
user.getInfo?.();

// Nullish Coalescing - default only for null/undefined
const value = null ?? 'default'; // 'default'
const count = 0 ?? 10; // 0 (0 is not null)

// Difference from || operator
const count2 = 0 || 10; // 10 (0 is falsy)

왜 이 문법들이 타자 연습에 포함되었는가? Why Are These Patterns Included in Typing Practice?

DevType의 JavaScript 타자 연습에는 위에서 설명한 모든 패턴이 포함되어 있습니다. 이유는 간단합니다: 현대 JavaScript 프로젝트에서 매일 마주치는 코드이기 때문입니다.

DevType's JavaScript typing practice includes all patterns explained above. The reason is simple: these are codes you encounter daily in modern JavaScript projects.

  • 화살표 함수와 배열 메서드 조합 (map, filter, reduce)
  • 객체/배열 구조분해를 사용한 함수 매개변수
  • async/await를 사용한 API 호출
  • 스프레드 연산자를 사용한 상태 업데이트 (React에서 필수)
  • Arrow functions with array methods (map, filter, reduce)
  • Function parameters with object/array destructuring
  • API calls with async/await
  • State updates with spread operator (essential in React)

이 패턴들을 타이핑으로 익히면, 코드를 읽을 때도 자연스럽게 이해할 수 있게 됩니다.

Learning these patterns through typing helps you naturally understand code when reading it.