JavaScript 독학 가이드 9 - ES6+ 최신 문법
2015년 ES6(ES2015)가 나오면서 JavaScript가 완전히 바뀌었어요. 코드가 훨씬 짧아지고 읽기 쉬워졌죠. 요즘 JavaScript 코드는 거의 다 ES6+ 문법으로 작성돼요. 옛날 문법만 알면 최신 코드 읽을 수가 없어요!
let과 const
이미 배웠지만 다시 한 번 강조할게요.
// var는 쓰지 마세요
var old = "옛날 방식";
// let: 변경 가능
let count = 0;
count = 1; // OK
// const: 변경 불가 (기본으로 사용)
const PI = 3.14;
// PI = 3.14159; // 에러!
실행 결과:
const는 재할당이 불가능합니다
원칙: const를 기본으로 쓰고, 꼭 바꿔야 할 때만 let
화살표 함수
더 짧고 간결한 함수 문법이에요.
// 기존 방식
function add(a, b) {
return a + b;
}
// 화살표 함수
const add = (a, b) => {
return a + b;
};
// 더 짧게 (한 줄이면 return, 중괄호 생략)
const add = (a, b) => a + b;
// 매개변수 하나면 괄호도 생략
const double = n => n * 2;
// 매개변수 없으면 빈 괄호
const greet = () => console.log("Hello");
실행 결과:
화살표 함수의 this
const person = {
name: "철수",
sayHi: function() {
setTimeout(function() {
console.log(this.name); // undefined (this가 바뀜)
}, 1000);
},
sayHello: function() {
setTimeout(() => {
console.log(this.name); // "철수" (this 유지됨)
}, 1000);
}
};
화살표 함수는 this를 상위 스코프에서 가져와요.
템플릿 리터럴
백틱(`)으로 문자열을 만들면 변수를 쉽게 넣을 수 있어요.
let name = "철수";
let age = 25;
// 옛날 방식
let intro1 = "제 이름은 " + name + "이고, 나이는 " + age + "살입니다.";
// 템플릿 리터럴
let intro2 = `제 이름은 ${name}이고, 나이는 ${age}살입니다.`;
// 표현식도 가능
let result = `10 + 5 = ${10 + 5}`; // "10 + 5 = 15"
// 여러 줄 문자열
let message = `
첫 번째 줄
두 번째 줄
세 번째 줄
`;
실행 결과:
템플릿 리터럴로 변수 삽입과 여러 줄 문자열을 쉽게 만들 수 있습니다
구조 분해 할당
객체나 배열에서 값을 꺼내는 편리한 방법이에요.
객체 구조 분해
let person = {
name: "철수",
age: 25,
email: "chulsu@test.com"
};
// 옛날 방식
let name = person.name;
let age = person.age;
// 구조 분해
let { name, age } = person;
console.log(name); // "철수"
console.log(age); // 25
// 다른 이름으로 저장
let { name: userName, age: userAge } = person;
// 기본값 설정
let { name, phone = "없음" } = person;
console.log(phone); // "없음"
실행 결과:
배열 구조 분해
let colors = ["빨강", "파랑", "초록"];
// 옛날 방식
let first = colors[0];
let second = colors[1];
// 구조 분해
let [first, second] = colors;
console.log(first); // "빨강"
console.log(second); // "파랑"
// 건너뛰기
let [, , third] = colors;
console.log(third); // "초록"
// 나머지 가져오기
let [red, ...rest] = colors;
console.log(rest); // ["파랑", "초록"]
실행 결과:
스프레드 연산자
배열이나 객체를 펼치는 연산자예요 (...).
배열 스프레드
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
// 배열 합치기
let combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4, 5, 6]
// 배열 복사
let copied = [...arr1];
copied.push(4);
console.log(arr1); // [1, 2, 3] (원본 안 바뀜)
console.log(copied); // [1, 2, 3, 4]
// 함수 인자로 전달
function sum(a, b, c) {
return a + b + c;
}
console.log(sum(...arr1)); // 6
실행 결과:
스프레드 연산자로 배열을 펼치고 복사할 수 있습니다
객체 스프레드
let person = { name: "철수", age: 25 };
let details = { email: "chulsu@test.com", phone: "010-1234-5678" };
// 객체 합치기
let user = { ...person, ...details };
console.log(user);
// { name: "철수", age: 25, email: "chulsu@test.com", phone: "010-1234-5678" }
// 객체 복사
let copied = { ...person };
// 속성 덮어쓰기
let updated = { ...person, age: 26 };
console.log(updated); // { name: "철수", age: 26 }
실행 결과:
Rest 파라미터
함수에서 여러 인자를 배열로 받아요.
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
// 일반 매개변수와 함께 사용
function greet(greeting, ...names) {
return `${greeting}, ${names.join(" and ")}!`;
}
console.log(greet("Hello", "철수", "영희")); // "Hello, 철수 and 영희!"
실행 결과:
Rest 파라미터로 가변 인자를 배열로 받을 수 있습니다
단축 속성명
객체 만들 때 변수명과 속성명이 같으면 생략 가능해요.
let name = "철수";
let age = 25;
// 옛날 방식
let person1 = {
name: name,
age: age
};
// 단축 속성명
let person2 = { name, age };
console.log(person2); // { name: "철수", age: 25 }
실행 결과:
변수명과 속성명이 같으면 한 번만 써도 됩니다
기본 매개변수
// 옛날 방식
function greet(name) {
name = name || "손님";
console.log(`안녕하세요, ${name}님`);
}
// ES6+
function greet(name = "손님") {
console.log(`안녕하세요, ${name}님`);
}
greet("철수"); // 안녕하세요, 철수님
greet(); // 안녕하세요, 손님님
실행 결과:
옵셔널 체이닝
객체의 속성에 안전하게 접근해요.
let user = {
name: "철수",
address: {
city: "서울"
}
};
// 옛날 방식
let zipcode = user && user.address && user.address.zipcode;
// 옵셔널 체이닝
let zipcode = user?.address?.zipcode;
console.log(zipcode); // undefined (에러 안 남)
// 함수 호출에도 사용
user.getName?.(); // getName이 있으면 호출, 없으면 undefined
실행 결과:
존재하지 않는 속성에 접근해도 에러가 발생하지 않습니다
Nullish 병합 연산자
null이나 undefined일 때만 기본값 사용해요.
let count = 0;
// || 사용 (문제 있음)
let result1 = count || 10;
console.log(result1); // 10 (0도 falsy라서)
// ?? 사용 (올바름)
let result2 = count ?? 10;
console.log(result2); // 0 (null/undefined가 아니므로)
let name = null;
let displayName = name ?? "손님";
console.log(displayName); // "손님"
실행 결과:
??는 null과 undefined만 체크하고, 0이나 빈 문자열은 유효한 값으로 취급합니다
배열 메서드
map
let numbers = [1, 2, 3, 4, 5];
let doubled = numbers.map(n => n * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
실행 결과:
filter
let numbers = [1, 2, 3, 4, 5];
let evens = numbers.filter(n => n % 2 === 0);
console.log(evens); // [2, 4]
실행 결과:
reduce
let numbers = [1, 2, 3, 4, 5];
let sum = numbers.reduce((total, num) => total + num, 0);
console.log(sum); // 15
실행 결과:
find / findIndex
let users = [
{ name: "철수", age: 25 },
{ name: "영희", age: 23 },
{ name: "민수", age: 27 }
];
let user = users.find(u => u.name === "영희");
console.log(user); // { name: "영희", age: 23 }
let index = users.findIndex(u => u.name === "영희");
console.log(index); // 1
실행 결과:
실전 예제
1. 사용자 정보 처리
function createUser({ name, age, email = "없음", ...rest }) {
return {
name,
age,
email,
createdAt: new Date(),
...rest
};
}
let user = createUser({
name: "철수",
age: 25,
phone: "010-1234-5678"
});
console.log(user);
// {
// name: "철수",
// age: 25,
// email: "없음",
// createdAt: 2025-11-25...,
// phone: "010-1234-5678"
// }
실행 결과:
구조 분해, 기본값, rest 파라미터, 단축 속성명을 모두 활용한 예제입니다
2. 배열 데이터 처리
let products = [
{ name: "노트북", price: 1000000, category: "전자제품" },
{ name: "마우스", price: 20000, category: "전자제품" },
{ name: "책상", price: 150000, category: "가구" }
];
// 전자제품만 필터링하고 10% 할인
let discounted = products
.filter(p => p.category === "전자제품")
.map(p => ({
...p,
price: p.price * 0.9
}));
console.log(discounted);
실행 결과:
filter와 map을 체이닝하여 데이터를 가공했습니다
3. 객체 병합
let defaults = {
theme: "light",
language: "ko",
notifications: true
};
let userSettings = {
theme: "dark"
};
let settings = { ...defaults, ...userSettings };
console.log(settings);
// { theme: "dark", language: "ko", notifications: true }
실행 결과:
스프레드 연산자로 기본 설정에 사용자 설정을 병합했습니다
다음 단계
다음 글에서는 비동기 처리와 API 호출을 배웁니다. Promise, async/await로 서버에서 데이터를 가져오고 처리하는 방법을 알아볼 거예요. JavaScript 독학 가이드의 마지막 편입니다!
ES6+ 문법은 현대 JavaScript의 필수예요. 이걸 모르면 최신 코드를 읽을 수가 없어요!
JavaScript 독학 가이드 시리즈:
← 블로그 목록으로