ES2015(ECMAScript 2015), 흔히 ES6로 알려진 이 버전은 자바스크립트 언어에 현대적인 프로그래밍 패러다임을 도입하고 개발 효율성을 크게 향상시킨 다양한 새로운 기능을 선보였습니다. 이 문서는 ES2015의 주요 기능들을 살펴보고 각 기능의 활용 예시를 제시합니다.
1. let 및 const
let과 const 키워드는 블록 스코프(Block Scope) 변수를 선언할 수 있게 하여 기존의 var 키워드와 달리 변수 유효 범위에 대한 혼란을 줄여줍니다. let은 재할당이 가능한 변수를, const는 한 번 할당되면 재할당이 불가능한 상수를 선언할 때 사용합니다.
let quantity = 10;
if (quantity > 5) {
let quantity = 20; // 이 quantity는 if 블록 내에서만 유효합니다.
console.log(`블록 내부 수량: ${quantity}`); // 출력: 블록 내부 수량: 20
}
console.log(`블록 외부 수량: ${quantity}`); // 출력: 블록 외부 수량: 10
const TAX_RATE = 0.1; // 변경할 수 없는 상수 선언
// TAX_RATE = 0.12; // 오류 발생: Assignment to constant variable.
2. 화살표 함수 (Arrow Functions)
화살표 함수는 함수를 정의하는 더욱 간결한 문법을 제공하며, 특히 this 바인딩 방식이 기존 함수와 다르게 자신만의 this를 생성하지 않고 상위 스코프의 this를 상속받습니다.
const calculateProduct = (val1, val2) => val1 * val2;
console.log(`곱셈 결과: ${calculateProduct(5, 4)}`); // 출력: 곱셈 결과: 20
// 'this' 바인딩 예시 (상위 스코프의 this를 유지)
// const user = {
// name: 'Alice',
// logName: function() {
// setTimeout(() => {
// console.log('이름: ' + this.name); // 여기서 'this'는 user 객체
// }, 100);
// }
// };
// user.logName();
3. 템플릿 리터럴 (Template Literals)
백틱(`` ` ``)을 사용하여 문자열을 정의하며, ${} 문법을 통해 변수나 표현식을 문자열 안에 쉽게 삽입할 수 있습니다. 여러 줄의 문자열을 작성할 때도 편리합니다.
const appName = "AwesomeApp";
const appVersion = "1.0.0";
console.log(`애플리케이션 이름: ${appName}, 버전: ${appVersion} 입니다.`);
// 출력: 애플리케이션 이름: AwesomeApp, 버전: 1.0.0 입니다.
const multiLine = `이것은
여러 줄에 걸쳐
작성된 문자열입니다.`;
console.log(multiLine);
4. 비구조화 할당 (Destructuring Assignment)
배열이나 객체에서 속성 또는 요소를 추출하여 개별 변수에 할당하는 것을 간편하게 할 수 있습니다. 코드의 가독성을 높이고 데이터를 다루는 방식을 효율적으로 만듭니다.
const [itemA, itemB] = ["사과", "바나나"];
console.log(`첫 번째 항목: ${itemA}`); // 출력: 첫 번째 항목: 사과
const userProfile = { id: 101, username: "dev_user", email: "dev@example.com" };
const { username, email } = userProfile;
console.log(`사용자명: ${username}, 이메일: ${email}`);
// 출력: 사용자명: dev_user, 이메일: dev@example.com
5. 기본 매개변수 (Default Parameters)
함수 매개변수에 기본값을 지정할 수 있습니다. 함수 호출 시 해당 매개변수에 값이 전달되지 않으면 기본값이 사용됩니다.
function calculatePrice(basePrice, discount = 0) {
return basePrice * (1 - discount);
}
console.log(`할인 없는 가격: ${calculatePrice(100)}`); // 출력: 할인 없는 가격: 100
console.log(`20% 할인 가격: ${calculatePrice(100, 0.2)}`); // 출력: 20% 할인 가격: 80
6. 전개 구문 (Spread Syntax) - ...
배열이나 객체를 펼치거나(spread) 병합할 때 사용됩니다. 배열 요소들을 새로운 배열에 쉽게 포함시키거나, 객체의 속성들을 새로운 객체로 복사하는 데 유용합니다. 또한, 함수 호출 시 배열을 인수로 전달할 때도 사용됩니다.
const primaryColors = ['빨강', '노랑'];
const allColors = ['파랑', ...primaryColors, '초록'];
console.log(`모든 색상: ${allColors}`); // 출력: 모든 색상: 파랑,빨강,노랑,초록
const configDefaults = { timeout: 3000, maxRetries: 3 };
const userSettings = { maxRetries: 5, enableCache: true };
const mergedSettings = { ...configDefaults, ...userSettings };
console.log('병합된 설정:', mergedSettings);
// 출력: 병합된 설정: { timeout: 3000, maxRetries: 5, enableCache: true }
7. 클래스 (Classes)
ES2015는 프로토타입 기반의 객체 지향 프로그래밍을 더 직관적인 클래스 문법으로 사용할 수 있게 합니다. constructor, methods, 상속(extends) 등을 지원하여 객체 지향 설계를 보다 쉽게 구현할 수 있습니다.
class Product {
constructor(name, price) {
this.name = name;
this.price = price;
}
displayInfo() {
return `${this.name}의 가격은 ${this.price}원 입니다.`;
}
}
const laptop = new Product("노트북", 1200000);
console.log(laptop.displayInfo()); // 출력: 노트북의 가격은 1200000원 입니다.
class ElectronicProduct extends Product {
constructor(name, price, brand) {
super(name, price); // 부모 클래스의 constructor 호출
this.brand = brand;
}
getBrand() {
return `브랜드: ${this.brand}`;
}
}
const smartphone = new ElectronicProduct("스마트폰", 800000, "XYZ");
console.log(smartphone.displayInfo() + ", " + smartphone.getBrand());
// 출력: 스마트폰의 가격은 800000원 입니다., 브랜드: XYZ
8. 프로미스 (Promises)
비동기 작업을 보다 효과적으로 처리하기 위한 패턴입니다. 미래의 어떤 시점에 결과를 반환하거나 오류를 발생시킬 수 있는 작업의 최종 완료 또는 실패를 나타내는 객체입니다. 콜백 지옥(Callback Hell)을 피하고 코드의 가독성을 높이는 데 기여합니다.
const fetchData = new Promise((resolve, reject) => {
setTimeout(() => {
const isSuccess = true; // 데이터를 성공적으로 가져왔다고 가정
if (isSuccess) {
resolve("서버에서 데이터를 성공적으로 로드했습니다!");
} else {
reject("데이터 로드 실패!");
}
}, 2000); // 2초 후 실행
});
fetchData
.then((message) => {
console.log(`성공: ${message}`); // 2초 후 출력
})
.catch((error) => {
console.error(`실패: ${error}`);
})
.finally(() => {
console.log('데이터 요청 작업 완료.');
});
9. 이터레이터 및 제너레이터 (Iterators & Generators)
이터레이터는 데이터 컬렉션을 순회하는 표준 방식을 제공합니다. 제너레이터는 function* 키워드로 선언되며, yield 키워드를 사용하여 실행을 일시 중지하고 재개할 수 있는 특별한 종류의 함수로, 커스텀 이터레이터를 쉽게 구현할 수 있게 합니다.
function* evenNumberGenerator(limit) {
let num = 0;
while (num <= limit) {
yield num;
num += 2;
}
}
const evens = evenNumberGenerator(6);
console.log(`첫 번째 짝수: ${evens.next().value}`); // 출력: 첫 번째 짝수: 0
console.log(`두 번째 짝수: ${evens.next().value}`); // 출력: 두 번째 짝수: 2
console.log(`세 번째 짝수: ${evens.next().value}`); // 출력: 세 번째 짝수: 4
console.log(`네 번째 짝수: ${evens.next().value}`); // 출력: 네 번째 짝수: 6
console.log(`더 이상 없음:`, evens.next()); // 출력: 더 이상 없음: { value: undefined, done: true }
10. 모듈 (Modules)
ES2015 모듈은 import와 export 키워드를 사용하여 코드를 재사용 가능한 단위로 분리하고 관리할 수 있게 합니다. 이를 통해 코드의 구조화, 종속성 관리, 그리고 이름 공간(namespace) 오염 방지에 큰 이점을 제공합니다.
// 파일: utils.js
export function subtract(val1, val2) {
return val1 - val2;
}
export const DEFAULT_COUNT = 100;
// 다른 파일 (예: main.js)에서 사용하는 방법:
// import { subtract, DEFAULT_COUNT } from './utils.js';
// console.log(`뺄셈 결과: ${subtract(50, 20)}`); // 출력: 뺄셈 결과: 30
// console.log(`기본 값: ${DEFAULT_COUNT}`); // 출력: 기본 값: 100
// (이 코드는 실제 브라우저 또는 Node.js 환경에서 모듈 로더와 함께 실행되어야 합니다.)