-
JavaScript의 ES란?
JavaScript를 공부한다면 누구나 ES6라는 것을 들어봤을 것이다.
여기서 ES란 ECMAScript의 줄임말로, Ecma International이라는 기구에서 정한 표준화된 JavaScript 언어 명세. 즉 약속이다. 뒤에 붙는 숫자들을 버전을 뜻한다. 2023년 기준으로 ES14까지 나왔지만, ES6(ES2015)가 가장 화두가 되는 이유는 명세 내용에 가장 큰 변화가 있었기 때문이다.
ES6(2015) 어떤 기능이 추가되었나?
1. let, const
기존의
var
키워드는 함수 레벨 스코프를 가지며 암묵적 재할당이 가능하였다. 이러한 호이스팅(hoisting) 현상으로 인해 발생되는 side effect를 최소화 하기위해 블록레벨 스코프를 가진let
,const
키워드가 추가되었다.// ES5 var button = document.getElementById("button1"); // ES6 const button = document.getElementById("button2"); let name = "Lee"; name = "Soo"; console.log(name); //Soo
2. Arrow function
() => {}
로 표기하며, 간결한 표기법으로 가독성이 향상되었다.new 생성자로는 사용할 수 없고 기존의 함수와 this 바인딩이 다르다.
- dynamic scope가 아닌 lexical scope의 this를 가지고 있다.
this
,arguments
,super
,new.target
을 Binding하지 않는다.
ES5 function VS ES6 Arrow function
ES5 function ES6 Arrow function function()
{}() => {}
dynamic scope lexical scope // ES5 var func = function(arg1, arg2) {console.log("ES5")} // ES6 let func = (arg1, arg2) => {console.log("ES6")}
3. Defalt parametor
기존에는 함수의 매개변수에 초깃값을 작성하려면 함수 내부에서 로직이 필요했으나,
파라미터에서 바로 할당이 가능하다.
4. Template literal
` `
(back tic: 백틱)을 이용하여 문자열 작성이 편리해지고 가독성도 좋아졌다.${ }
를 통해 표현식 삽입도 가능하며, Multi-line string이 가능해졌다. 문자열 줄바꿈의 경우, 기존에는\n
과+
를 작성했으나, ES6에서는 백틱 내부에서 줄바꿈을 해주면 인식이 된다.// ES5 var name = "Lee" var age = 20 console.log("안녕하세요!\n저의 이름은 " + name + " 이고, 나이는 " + age + "입니다.") // output // 안녕하세요! // 저의 이름은 Lee 이고, 나이는 20입니다. // ES6 let name = "Soo" let age = 20 console.log(`안녕하세요! 저의 이름은 ${name}이고, 나이는 ${age}입니다.`) // output // 안녕하세요! // 저의 이름은 Soo 이고, 나이는 20입니다.
5. Class
클래스는 객체 생성방식 중 하나이며, 자바스크립트는 프로토타입 기반의 객체지향 프로그래밍이다.
ES5에서는 생성자 함수와 프로토타입, 클로저를 사용하여 객체 지향 프로그래밍을 구현하였다.
// ES5 var Person = (function () { // Constructor function Person(name) { this._name = name; } // public method Person.prototype.sayHi = function () { console.log('Hi! ' + this._name); }; // return constructor return Person; }()); var me = new Person('Lee'); me.sayHi(); // Hi! Lee. console.log(me instanceof Person); // true
ES6 클래스는
class
키워드를 사용하여 정의한다.// 클래스 선언문 class Person { // constructor(생성자) constructor(name) { this._name = name; } sayHi() { console.log(`Hi! ${this._name}`); } } // 인스턴스 생성 const me = new Person('Lee'); me.sayHi(); // Hi! Lee console.log(me instanceof Person); // true
6. Module
모듈이란 애플리케이션을 구성하는 개별적 요소로서 재사용 가능한 코드조각을 말한다. 세부사항은 캡슐화시키고, API 부분만 외부에 노출한다.
사용법은 다음과 같다.
<script type="module" src="app.mjs"></script>
type에 module을 추가하고, 파일 확장자를 mjs로 변경시킨다.
모듈은 모듈 스코프를 가지며,
export
,import
키워드로 사용한다.7. Destructuring
구조화된 배열 또는 객체를 Destructuring(비구조화, 파괴)하여 개별적인 변수에 할당하는 것이다. 배열 또는 객체 리터럴에서 필요한 값만을 추출하여 변수에 할당하거나 반환할 때 유용하다.
배열 디스트럭처링 (Array destructuring)
// ES5 var arr = [1, 2, 3]; var one = arr[0]; var two = arr[1]; var three = arr[2]; console.log(one, two, three); // 1 2 3
ES5에서는 배열의 인덱스를 직접 할당해주었다.
// ES6 Destructuring const arr = [1, 2, 3]; // 배열의 인덱스를 기준으로 배열로부터 요소를 추출하여 변수에 할당 // 변수 one, two, three가 선언되고 arr(initializer(초기화자))가 Destructuring(비구조화, 파괴)되어 할당된다. const [one, two, three] = arr; // 디스트럭처링을 사용할 때는 반드시 initializer(초기화자)를 할당해야 한다. // const [one, two, three]; // SyntaxError: Missing initializer in destructuring declaration console.log(one, two, three); // 1 2 3
ES6의 배열 디스트럭처링은 배열의 각 요소를 배열로부터 추출하여 변수 리스트에 할당한다. 이때 추출/할당 기준은 배열의 인덱스이다. 배열 디스트럭처링을 위해서는 할당 연산자 왼쪽에 배열 형태의 변수 리스트가 필요하다.
ES6의 배열 디스트럭처링은 배열에서 필요한 요소만 추출하여 변수에 할당하고 싶은 경우에 유용하다.
객체 디스트럭처링 (Object destructuring)
// ES5 var obj = { firstName: 'Soo', lastName: 'Lee' }; var firstName = obj.firstName; var lastName = obj.lastName; console.log(firstName, lastName); // Soo Lee
ES5에서 객체의 각 프로퍼티를 객체로부터 디스트럭처링하여 변수에 할당하기 위해서는 프로퍼티 이름(키)을 사용해야 한다.
// ES6 Destructuring const obj = { firstName: 'Soo', lastName: 'Lee' }; // 프로퍼티 키를 기준으로 디스트럭처링 할당이 이루어진다. 순서는 의미가 없다. // 변수 lastName, firstName가 선언되고 obj(initializer(초기화자))가 Destructuring(비구조화, 파괴)되어 할당된다. const { lastName, firstName } = obj; console.log(firstName, lastName); // Soo Lee
객체 디스트럭처링을 위해서는 할당 연산자 왼쪽에 객체 형태의 변수 리스트가 필요하다. 객체 디스트럭처링은 객체에서 프로퍼티 이름(키)으로 필요한 프로퍼티 값만을 추출할 수 있다.
8. Promise
자바스크립트는 비동기 처리를 위한 하나의 패턴으로 콜백 함수를 사용한다. 하지만 콜백 헬(Callback Hell)을 발생시켜 가독성이 좋지 않고 비동기 처리 중 발생한 에러의 처리가 곤란하며 한계가 있다.
// Callback Hell step1(function(value1) { step2(value1, function(value2) { step3(value2, function(value3) { step4(value3, function(value4) { step5(value4, function(value5) { // value5를 사용하는 처리 }); }); }); }); });
이를 해결하기 위해 ES6부터 프로미스(Promise)가 도입되었고, 프로미스 후속처리 메서드를 통해 에러처리를 효과적으로 할 수 있게 되었다. 프로미스는 전통적인 콜백 패턴이 가진 단점을 보완하며 비동기 처리 시점을 명확하게 표현할 수 있다는 장점이 있다.
// Promise 객체의 생성 const promise = new Promise((resolve, reject) => { // 비동기 작업을 수행한다. if (/* 비동기 작업 수행 성공 */) { resolve('result'); } else { /* 비동기 작업 수행 실패 */ reject('failure reason'); } });
🔗 Reference
댓글