javascript ECMAScript 2015(ES6)로 개발할 때 반드시 알아야할 9가지
ECMAScript2015로 개발하기 위해 알아야 할 9가지를 정리해 보려고 합니다.
먼저 간단하게 ECMAScript를 소개 하겠습니다.
ECMAScript
옛날 옛적에 넷스케이프(NE)와 인터넷익스플로러(IE)가 주도권 경쟁을 하던 시절~~
넷스케이프(NE)는 javascript를 지원했고 인터넷익스플로러(IE)는 Jscript를 지원 했었습니다.
윈도우즈에 끼워팔기 신공으로 점차 득세를 하기 시작한 인터넷익스플로러는 그만 자만심에 빠져 Jscript를 표준이 아닌 적당히 자기만의 기능을 추가하기 시작했습니다. 내가 점유율이 높으니 모든 브라우저들이 내가 만든 기준을 따라 올 거라 생각을 했던 것입니다.
하지만 망하기는 했지만 넷스케이프도 그렇게 호락호락하지 않았습니다. 자신이 밀고 있던 javascript의 핵심 개발 언어를 ECMA 인터내셔널에 제출하고 표준화를 시도 했던 것입니다. 그리고 1996년에 ECMA-262(ES1)으로 명명된 표준 스크립트 기술 규격이 발표되었습니다.
이때부터 ES3 -> ES5 -> ES6(ES2015) -> ES7(ES2016)로 표준을 발표했고 우리가 알고있는 javascript는 이 표준 언어를 적용하여 개선을 하기 시작했습니다.
파이어폭스, 크롬, 오페라, 사파리 등.. 다양한 웹브라우저들이 이 표준을 적용해 나가시 시작했고 웹표준이 대세로 자리를 잡으면서 결국 IE도 더이상 버티지 못하고 IE7부터 서서히 표준을 따라가기 시작했습니다. 하지만 너무 늦은 대응으로 결국 점유율 랭킹 1위를 크롬에게 넘겨주고 말았습니다.
ECMAScript 네이밍
ECMA버전을 보면 어떤 것은 숫자, 어떤것은 날짜가 적혀있어서 헷갈린 경우가 있습니다. 저도 그랬구요.
먼저 버전 순서는 아래와 같습니다.
ES3
-> ES5
-> ES6(ES2015)
-> ES7(ES2016)
ES3, ES5에서 3과 5는 버전을 의미합니다.
주의할 점은 ES4
버전은 없습니다.
ES6버전의 발표는 2015년 6월에 발표가 되었습니다. 그래서 ES6 또는 ES2015라고 부르기도 합니다. 똑같은 것입니다.
마찬가지로 ES7버전은 2016년에 발표가 되었기 때문에 ES7 또는 ES2016이라고 부르게 되었습니다.
무조건 최신버전이라고 좋은것은 아닙니다. 왜냐하면 옛날 버전의 웹브라우저를 사용하는 어떤사람은 ECMA의 최신 버전을 해석하지 못해서 깨진 화면이나 작동하지 않는 기능을 경험하는 경우가 있기 때문입니다.
그래서 적당한 ECMA버전으로 타협을 보고 프로젝트를 진행하거나 아니면 최신버전의 ECMA를 낮은 버전의 ECMA로 변환해 주는 BABEL같은 변환기를 사용해야 합니다.
ECMAScript 2015 (ES6 또는 ES2015)
현재 ECMAScript 2016 (ES7)까지 버전이 나와 있기는 하지만 현재 시점에서 대부분 개발은 ECMAScript 2015버전을 많이 사용합니다.
그래서 ECMAScript 2015 (ES6)개발 시 알아야 할 9가지 요소를 설명하겠습니다.
모듈
ES2015부터 javascript가 모듈이라는 개념을 도입함에 따라 대규모 프로젝트를 진행할 수 있는 토대가 되었습니다.
모듈은 보통 기능별 또는 화면별로 분리해서 js파일로 따로 따로 만들어 저장해 놨다가 필요할 때 마다 import
하여 사용할 수 있게 하는 기술입니다.
그러한 특성 때문에 모듈을 재활용 할 수 있어서 프로젝트 진행 할 때 쉽고 빠르게 구축을 할 수 있게 되었습니다.
모듈은 export
와 import
로 구성이 되어 있습니다.
모듈을 만들고 남들이 불러와 사용할 수 있기를 바라는 변수
, 함수
, 객체
, 클래스
에 대해서 export
를 써주면 다른 모듈에서 import
로 불러다 사용할 수 가 있습니다.
Export 설정 시
// 저장한 파일명은 aaa.js
export let a = "반가워요";
export function add(a, b) { return a + b }
Import로 불러오기
import {a, add} from './aaa.js'; //확장자인 .js는 생략 가능합니다.
console.log(a); // => 반가워요
console.log(add(100, 50)); // => 150
클래스
ES2015버전에서 CLASS를 공식 제정하였습니다. 기존 버전에서는 CLASS를 사용할 수 없어서 유사 CLASS로 편법으로 사용 했었습니다. 이제는 공식적으로 지원이 가능합니다.
기본 구현은 아래와 같습니다.
class Sayings {
constructor(a, b) {
this.a = a;
this.b = b;
}
static getSay() { return this.a; }
toSaying() {
return `a=${this.a} 이고 b=${this.b} 입니다.`;
}
}
let c1 = new Sayings('dog', 'cat');
console.log(c1.getSay()); // => 'dog'
console.log(c1.toSaying()); // => a=dog 이고 b=cat 입니다.
또한 상속도 지원합니다.
class Animal extends Sayings { }
let와 const
기존의 javascript에서 변수를 선언할때는 무조건 var
을 사용했었습니다.
그러나 var
는 Hosting, 블록단위 스코프 미지원, 중복선언 허용 등 몇가지 문제가 있었습니다.
var msg = "TEST";
let
이러한 문제를 인식하고 ES2015에서 let
와 const
를 재정했습니다.
그래서 let키워드를 사용함으로써 호이스팅 문제도 해결했고, 블록단위 스코프를 지원하게 되었습니다.
let
이 제정되었어도 var
도 같이 사용가능합니다. 하지만 가능하면 let
를 사용할 것을 추천합니다.
let msg = "TEST";
const
const
는 상수처럼 한번 값이 지정되면 변하지 않는 변수를 선언하며, 블록 스코트도 지원을 합니다.
const msg = "TEST";
기본 파라미터와 가변 파라미터
함수를 사용 시 Function이 받는 파라미터에 대해 기본과 가변의 파라미터를 지정할 수 있습니다.
기본 파라미터
보통 함수를 호출할 때 기존에 지정된 함수와 동일하지 않은 갯수의 파라미터로 호출을 할 경우 오류가 발생했었는데,
ES2015에서 기본 파라미터를 제정하여 더 적은 파라미터로 함수를 호출할 경우 미리 지정한 기본 파라미터 값으로 자동 대체되어 이런 문제를 해결하였습니다.
function addFn(a, b, c="없음", d="없음") { }
addFn("나무", "숲"); // 정상 => c, d가 "없음"으로 자동 입력
addFn("나무", "숲", "언덕"); // 정상 => d가 "없음"으로 자동 입력
addFn("나무", "숲", "언덕", "바람"); // 정상 => 기존 버전과 동일
여기에서 addFn()
호출 시 c
와 d
의 값을 넣지 않은 경우 기본 값인 "없음
"이 자동으로 들어가게 됩니다.
가변 파라미터
만약 함수 호출 시 저정된 파라미터의 갯수보다 많게 요청될 시에는 기본 파라미터 외의 넘어온 파라미터는 배열로 묶어서 별도로 받을 수 있게 해 줍니다.
사용법은 ...
과 변수명을 붙혀서 사용하면 됩니다.
function addFn(a, b, ...etc1) {
}
addFn("나무", "숲"); // 정상 => c, d가 "없음"으로 자동 입력
addFn("나무", "숲", "언덕"); // 정상 => etc1 = ["언덕"]
addFn("나무", "숲", "언덕", "바람"); // 정상 => etc1 = ["언덕", "바람"]
addFn("나무", "숲", "언덕", "바람". "돌"); // 정상 => etc1 = ["언덕", "바람", "돌"]
위의 함수에서 a
와 b
파라미터 외의 넘어온 파라미터 값들은 배열형태로 etc1
로 들어가게 됩니다.
구조 분해 할당
구조 분해 할당은 배열이나 객체로 저장되어 있는 값을 한번에 자동으로 지정된 변수에 나누어서 할당해 주는 것을 말합니다.
배열의 구조분해 할당
let a = [10, 20, 30, 40, 50];
let [b, c, d] = a; // ==> b=10, c=20, d=30 으로 할당됨
객체의 구조분해 할당
let a = {bb:10, cc:20, dd:30};
let {bb:b, cc:c, dd} = a; // ==> b=10, c=20, dd=30 으로 할당됨
화살표 함수
화살표 함수는 기존의 함수 표현식을 간결하게 줄여주며, 해당 함수 상위의 this
를 그대로 받아서 처리를 할 수 있습니다.
원래는 함수에서 상위의 this
를 받아서 사용하려면 bind
, apply
, call
등의 메서드를 사용했었어야 했는데 화살표함수에서는 바로 this
를 받을 수 있습니다.
let a1 = () => { return "test" };
let a2 = (c, d) => { return c + d };
let a3 = (c, d) => c + d;
a1(); // => a1 = "test";
a2(10, 20); // => a2 = 30;
a3(10, 20); // => a3 = 30;
템플릿 리터럴
템플릿 리터럴은 문자열에 변수를 표현할 때 예전에는 힘들게 작성하던 것을 간결하고 보기 쉽게 해주는 기능입니다.
문장을 역따옴표 로 묶고 변수에 대해 ${변수명}
으로 표시하여 작성할 수 있습니다.
let a = "홍길동";
let b = "월매";
let c = 50;
let d = 80;
// 기존방식 (복잡함)
var str = a + "와 " + b + "의 나이를 합산하면 " + (c + d) + "살 입니다.";
// 템플릿 리터럴 사용 방식 (간결함)
let str = `${a}와 ${b}의 나이를 합산하면 ${c + d}살 입니다.`;
Map과 Set
ES2015에서 추가된 요소 중 Map
과 Set
도 있습니다.
Map
은 객체와 비슷하고 Set
은 배열과 비슷한 모습을 하고 있습니다.
아무래도 객체와 배열을 좀 더 쉽고 빠르게 사용할 수 있게 하기 위해 만들지 않았나 생각해 봅니다.
Map
Map은 객체와 비슷하게 간단한 키와 값으로 서로 매핑을 시켜 저장해 놓고 필요할때 쉽게 불러 사용할 수 있습니다.
다음 코드는 Map
이 제공하는 기본적인 기능입니다.
(참고 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Keyed_collections)
var sayings = new Map();
sayings.set("dog", "woof");
sayings.set("cat", "meow");
sayings.set("elephant", "toot");
sayings.size; // 3
sayings.get("fox"); // undefined
sayings.has("bird"); // false
sayings.delete("dog");
for (var [key, value] of sayings) {
console.log(key + " goes " + value);
}
// "cat goes meow"
// "elephant goes toot"
Set
Map
이 객체
와 비슷하다면 Set
은 배열
과 비슷하다고 보시면 됩니다.
Set의 특징은 배열과 달리 중복된 값을 허용하지 않습니다. set내에서는 값이 하나만 존재하게 됩니다.
var mySet = new Set();
mySet.add(1);
mySet.add("some text");
mySet.add("foo");
mySet.has(1); // true
mySet.delete("foo");
mySet.size; // 2
for (let item of mySet) console.log(item);
// 1
// "some text"
배열과 Set는 서로 상호변환이 가능합니다.
Array.from(mySet);
[...mySet2];
mySet2 = new Set([1,2,3,4]);
Set은 기본적으로 합집합의 요소를 가지게 되며 교집합, 차집합은 filter로 구현을 할 수 있습니다.
let a = new Set(["dog", "cat", "elephant"]);
let b = new Set(["fox", "dog", "bird"])
// 합집합(기본) => Set {"dog", "cat", "elephant", "fox", "bird"}
let union = new Set( [...a.value()], [...b.value()] );
// 교집합 => Set {"dog"}
let intersection = new Set( [...a.value()].filter(e => b.has(e)) );
// 차집합 => Set {"cat", "elephant", "fox", "bird"}
let diff = new Set( [...a.value()].filter(e => !b.has(e)) );
Promise
AJAX로 비동기 처리를 할때 콜백지옥에 빠지지 않고 보기좋게 처리하기 위해 Promise를 제정하였습니다.
보통 Promise
와 then
으로 구성하게 됩니다.
그리고 오류를 받아 처리하기 위해 catch
도 세트로 사용합니다.
Promise설정시 resolve
와 reject
파라미터를 사용하게 되는데, resolve()
는 then
이 받고 reject()
는 catch
가 받게 됩니다.
var promise1 = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve('foo'); // then으로 넘김
}, 300);
reject('error');
});
promise1.then(function(value) { // resolve()로 넘긴 값을 value로 받음
console.log(value);
// expected output: "foo"
});
promise1.catch(function(value) { // reject()로 넘긴 값을 value로 받음
console.log(value);
// expected output: "error"
});
console.log(promise1);
// expected output: [object Promise]
이렇게 9가지 신비롭고 뛰어난 기능을 알고 사용하시면 javascript를 개발하는데 많은 도움이 될 것입니다.