지난 포스팅에 이어 ES6 문법을 정리해보려고 합니다.
ES6(ECMAScript 2015)는 Javascript 표준의 6번째 버전입니다.
주요 차이점은 아래의 10가지입니다.
1. let과 const
2. 템플릿 리터럴 (Template Literals)
3. 화살표 함수 (Arrow Function)
4. 구조분해 할당 (Destructuring Assignment)
5. 기본 매개변수 (Default Parameters)
6. 스프레드 연산자 (...)와 나머지 파라미터
7. 클래스 (Class)
8. 모듈 (Modules)
9. 프로미스 (Promises)
10. Symbol 타입
ES6는 말 그대로 '표준'입니다.
현대적인 코드를 사용하면 코드가 간결해지고 생산성이 향상될 수 있습니다.
최근 프론트엔드에서는 ES6+를 요구하고 있지만, 과거 버전에 대한 이해도 중요합니다.
1. 레거시 코드(기존의 코드)를 최신 문법으로 리팩토링 할 수 있는가?
2. 구글링한 과거 버전의 코드를 해석해서 유지 보수할 수 있는가?
이 두 가지를 위해서 ES5와 같은 과거 버전의 표준 또한 구분할 수 있어야 합니다.
그리고 모든 회사가 최신 문법을 사용하진 않기 때문에 회사의 규칙에 맞게 사용하는 것이 올바르다고 할 수 있습니다.
지난 포스팅을 보시고 싶은 분들은 아래 링크를 통해 확인 부탁드립니다!
[개발/Frontend] - [Javascript] ES6 기초 문법 정리 (1)
6. 스프레드 연산자 (...)와 나머지 파라미터 (... Operator and Rest Parameters)
스프레드 연산자 (Spread Operator)
Javascript의 spread 연산자(...)를 사용하면 기존 배열이나 객체의 전체 또는 일부를 다른 배열이나 객체로 빠르게 복사할 수 있습니다.
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// 기존 방법
const arr3 = arr1.concat(arr2)
console.log(arr3) // ['1', '2', '3', '4', '5', '6']
// Spread Operator 사용
const arr3 = [...arr1, ...arr2];
console.log(arr3) // ['1', '2', '3', '4', '5', '6']
위 코드처럼 두 배열을 하나의 배열로 병합하려고 할 때 기존에는 concat 매서드를 활용하여 병합했지만
ES6에서는 Spread 연산자를 사용해서 간편하게 병합이 가능합니다.
let user = { name: 'Kim', city: 'Seoul' };
user = { ...user, age: 28 };
console.log (user); // { name: 'Kim', city: 'Seoul', age: 28 }
user = { ...user, name: 'John', age: 30 }
console.log(user); // { name: 'John', city: 'Seoul', age: 30 }
객체에서는 spread 연산자를 사용해서 프로퍼티를 업데이트하거나 복사할 수 있습니다.
나머지 파라미터 (Rest Parameter)
: 이름 앞에 ...을 붙여서 정의한 매개변수.
나머지 파라미터는 함수에 전달된 파라미터들을 배열로 전달 받습니다.
// args에 1,2,3,4,5가 한꺼번에 배열로 담겨 인자로 넘겨진다.
function func1(...args) {
console.log(`args: [${args}]`)
// args: [1,2,3,4,5]
}
func1(1,2,3,4,5);
// arg1에는 1, arg2에는 2, arg3에는 나머지 3,4,5가 배열로 담겨 인자로 넘겨진다.
function func2(arg1, arg2, ...arg3) {
console.log(`arg1: ${arg1}, arg2: ${arg2}, arg3: [${arg3}]`)
// arg1: 1, arg2: 2, arg3: [3,4,5]
}
func2(1,2,3,4,5);
위 코드처럼 여러개의 파라미터가 함수로 전달되었을 때, 나머지 파라미터를 이용해서 배열로 전달 받을 수 있습니다.
나머지 파라미터는 먼저 선언된 매개변수에 할당된 파라미터를 제외한 나머지 파라미터들이 모두 배열에 할당되어 전달되기 때문에
함수 정의에는 하나의 나머지 파라미터(...)만 존재할 수 있으며 반드시 마지막 매개변수여야 합니다.
7. 클래스 (Class)
기존의 자바스크립트에서는 prototype을 이용해 유사하게 상속을 구현했었습니다.
ES6이후 Class가 나오면서 명료하고 간편하게 객체를 생성하고, 상속을 구현할 수 있습니다.
앞선 포스팅에서 언급했던 것처럼 클래스 선언은 호이스팅이 일어나지 않습니다.
클래스는 반드시 정의한 뒤에 사용해야 합니다.
자세한건 아래 코드를 보면서 설명하겠습니다.
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
this.city = city;
}
nextYearAge() { // 메서드 생성
return Number(this.age) + 1;
}
}
// 클래스 상속
class introducePerson extends Person {
constructor(name, age, city, futureHope) {
// super 키워드를 이용해서 자식 class에서 부모 메서드를 호출
super(name, age, city);
this.futureHope = futureHope
}
introduce () {
return `저는 ${this.city}에 사는 ${this.name} 입니다.
내년엔 ${super.nextYearAge()}살이며,
장래희망은 ${this.futureHope} 입니다.`}
}
let kim = new introducePerson('kim','23','seoul', '개발자');
console.log(kim.introduce())
- super 키워드를 사용하여 자식 클래스에서 부모 클래스의 매서드나 맴버 변수를 호출할 수 있습니다.
- Getter 혹은 Setter를 정의하고 싶을 때는 메소드 이름 앞에 get 또는 set를 붙여주면 됩니다.
- extends 키워드를 사용하여 클래스에서 다른 클래스로 상속하면서 클래스의 기능을 확장해나갈 수 있습니다.
- 클래스에서 일반적인 방법으로 프로퍼티를 선언하고 할당하면 Public Property(공개 프로퍼티)가 된다.
→ 외부에서 프로퍼티에 접근하여 값을 사용하거나 수정이 가능함.
- 클래스에서 프로퍼티 앞에 # 키워드를 작성하여 선언하면 Private Property(비공개 프로퍼티)가 된다.
→ 오직 클래스 안에서만 사용, 변경이 가능. 외부 접근 불가.
8. 모듈 (Modules)
ES6에서 모듈이 표준화되어, 코드 재사용성과 관리 편리성 높아졌습니다.
import, export 키워드를 사용하여 선언적이고 정적인 모듈 시스템을 사용할 수 있습니다.
그렇기 때문에 가독성 측면에서 유리한 점이 많습니다.
또한 비동기 방식으로 작동하고 모듈에서 실제로 쓰이는 부분만 불러오기 때문에 성능과 메모리 부분에서도 유리합니다.
named export
CommonJS에서는 내보낼 복수 객체들을 exports 변수의 속성으로 할당하는 방식을 사용했는데,
ES6에서는 import 키워드와 함께 export 키워드를 사용해서 명시적으로 선언해 줍니다.
이 때 내보내는 변수나 함수의 이름이 그대로 불러낼 때 사용하게 되는 이름이 되므로 Named exports라고 부릅니다.
아래는 미국과 캐나다 달러를 상호 변환해주는 자바스크립트 예제 코드입니다. 이 파일에는 3개의 함수가 있는데 아래 2개의 함수만 다른 파일에서 접근할 수 있도록 내보내기를 하였습니다. 첫번째 방법처럼 선언과 동시에 내보낼 수도 있고, 두번째 방법처럼 선언 후에 별도로 내보낼 수도 있습니다.
currency-functions.js
const exchangeRate = 0.91;
// 내보내지 않음
function roundTwoDecimals(amount) {
return Math.round(amount * 100) / 100;
}
// 첫번째 내보내기 방법
export function canadianToUs(canadian) {
return roundTwoDecimals(canadian * exchangeRate);
}
// 두번째 내보내기 방법
const usToCanadian = function(us) {
return roundTwoDecimals(us / exchangeRate)
}
export { usToCanadian }
named export
CommonJS에서는 내보낼 단일 객체를 module.exports 변수에 할당하는 방식을 썼었는데, ES6에서는 그 대신 export default 키워드를 사용해서 명시적으로 선언해줍니다. 하나의 모듈에서 하나의 객체만 내보내기 때문에 이를 Default Export라고 부릅니다.
아래 예제는 두개 함수를 객체로 묶어서 내보내기를 한 코드입니다. 이름이 필요없기 때문에 별도 변수 할당 없이 바로 객체를 내보내기 할 수 있습니다. 내보낼때 어떤 이름도 지정하지 않기 때문에 불러올 때도 아무 이름이나 사용할 수 있습니다.
currency-object.js
const exchangeRate = 0.91;
// 내보내지 않음
function roundTWoDecimals(amount) {
return Math.round(amount * 100) / 100;
}
// 내보내기
export default {
canadianToUs(canadian){
return roundTwoDecimals(canadian * exchangeRate);
},
usToCanadian: function(us){
return roundTwoDecimals(us / exhangeRate);
},
}
변수에 할당을 하여 내보내기를 하고 싶다면 다음과 같이 작성할 수도 있습니다.
const obj = {
canadianToUs(canadian) {
return roundTwoDecimals(canadian * exchangeRate)
},
}
obj.usToCanadian = function (us) {
return roundTwoDecimals(us / exchangeRate)
}
export default obj
Import
여러 객체(Named Exports)를 불러올 때는 ES6의 Destructuring (구조 분해 할당) 문법을 사용해서 필요한 객체만 선택적으로 전역에서 사용하거나, 모든 객체에 별명을 붙이고 그 별명을 통해서 접근할 수도 있습니다.
test-currency-function.js
// Desturturing
import { canadianToUs } from "./currency-functions"
console.log("50 Canadian dollars equals this amount of US dollars:");
console.log(canadianToUs(50));
// Alias
import * as currency from "./currency-functions"
console.log("30 US dollars equals this amount of Canadian dollars:");
console.log(currency.usToCanadian(30));
하나의 객체(Default Export)를 불러올 때는 간단하게 import 키워드를 사용해서 원하는 이름을 주고 해당 객체를 통해 속성에 접근하면 됩니다.
test-currency-object.js
import currency from "./currency-object"
console.log("50 Canadian dollars equals this amount of US dollars:")
console.log(currency.canadianToUs(50))
console.log("30 US dollars equals this amount of Canadian dollars:")
console.log(currency.usToCanadian(30))
9. 프로미스 (Promises)
Promise는 비동기 작업을 더 쉽게 관리하게 해주는 객체입니다.
Promise는 대기(pending), 이행(fulfilled), 거부(rejected)의 3가지 상태를 가질 수 있습니다.
- 대기(pending): 비동기 처리 로직이 아직 완료되지 않은 상태
- 이행(fulfilled): 비동기 처리가 완료되어 프로미스가 결과 값을 반환한 상태
- 거부(rejected): 비동기 처리가 실패하거나 오류가 발생한 상태
사용 방법
Promise 객체는 new Promise() 생성자 함수를 통해 생성됩니다.
이 생성자 함수는 resolve와 reject라는 이름의 두 개의 콜백 함수를 매개변수로 받습니다.
const myPromise = new Promise((resolve, reject) => {
if (/* 비동기 작업이 성공 */) {
resolve('성공');
} else {
reject('실패');
}
});
.then()과 .catch()
Promise 객체에는 .then()과 .catch()라는 두 개의 메서드가 있습니다.
.then()은 Promise가 이행된 경우 실행할 콜백을 등록하며, .catch()는 거부된 경우 실행할 콜백을 등록합니다.
myPromise
.then(result => {
console.log('성공:', result);
})
.catch(error => {
console.log('실패:', error);
});
.then()은 새로운 Promise 객체를 반환하기 때문에 메서드 체이닝을 통해 여러 비동기 작업을 순차적으로 처리할 수 있습니다.
fetchSomething()
.then(processData)
.then(saveData)
.catch(handleErrors);
코드 분석
- fetchSomething()
fetchSomething()은 Promise를 반환하는 비동기 함수입니다.
이 함수는 원격 리소스를 가져오는 작업이나 다른 비동기 작업을 수행할 수 있습니다. - .then(processData)
fetchSomething() 함수가 성공적으로 완료되면 (resolve가 호출되면), processData 함수가 실행됩니다.
processData는 fetchSomething() 함수의 결과를 인수로 받아 처리합니다. - .then(saveData)
processData 함수가 성공적으로 완료된 후 그 결과를 saveData 함수로 전달합니다.
saveData 함수는 이 결과를 저장하거나 다른 작업을 수행할 수 있습니다. - .catch(handleErrors)
fetchSomething, processData, 또는 saveData 중 하나라도 실패하면 (reject가 호출되면), handleErrors 함수가 실행됩니다. 이 함수는 발생한 오류를 처리합니다.
10. Symbol 타입
자바스크립트 ES6에서 Symbol이라는 데이터 유형을 추가하였습니다.
자바스크립트에는 아래와 같은 원시 데이터 유형을 가지고 있습니다.
- Boolean
- Null
- Undefined
- Number
- String
- Symbol (new)
Symbol()
Symbol은 Symbol() 함수로 생성합니다.
Symbol은 고유한 데이터입니다. 즉 변경 불가능한 원시 타입의 값입니다.
Symbol은 주로 이름의 충돌 위험이 없는 유일한 객체의 프로퍼티 키(property key)를 만들기 위해 사용됩니다.
const a = Symbol("id");
const b = Symbol("id");
// 동일한 description을 넣어도 각각 다른 데이터로 인식
console.log(a == b); // false
Symbol은 유일성이 보장되는 자료형이기 때문에, 설명이 동일한 심볼을 여러 개 만들어도 각 심볼값은 다릅니다.
Symbol에 description값은 어떤 것에도 영향을 주지 않는 이름표 역할만을 합니다.
Symbol.for()
Symbol() 은 고유한 심볼을 반환합니다.
하지만 Symbol.for() 는 전역으로 존재하는 global symbol table 의 목록을 참조합니다.
때문에 Symbol.for(token string) 으로 정의할때, token string 으로 정의 된 심볼이 있다면, 해당 심볼을 반환하게 됩니다.
// 전역 Symbol 레지스트리에 foo라는 키로 저장된 Symbol이 없으면 새로운 Symbol 생성
const s1 = Symbol.for('foo');
// 전역 Symbol 레지스트리에 foo라는 키로 저장된 Symbol이 있으면 해당 Symbol을 반환
const s2 = Symbol.for('foo');
console.log(s1 === s2); // true
'개발 > Frontend' 카테고리의 다른 글
| [Javascript] ES6 기초 문법 정리 (1) (0) | 2025.05.25 |
|---|