이전 포스트 ECMAScript와 Babel 에서 ECMAScript 2015+ 의 Javascript 코드를 런타임 환경에 적용하기 위해서는 그에 맞는 버전으로 호환시켜줘야 하며 이를 위한 툴체인으로 Babel 이라는 것이 있다는 것까지 정리해보았습니다.
이번 포스트에서는 그렇다면 ECMAScript 2015에 어떤 syntax가 추가되었는지 까지 알아보는 시간을 가져보려합니다. 이번 주제를 위해 다양한 포스팅을 읽었고 그 중 principal 한 사이트를 번역하는 것이 도움이 될 것 같아 lukehoban 의 es6features 를 번역 했습니다.
ECMAScript 6 git.io/es6features
Introduction
ECMAScript 2015 또는 ECMAScript 6는 ECMAScript 표준의 가장 최신 버전입니다. ES6는 2009년 ES5가 표준화된 이후 중대한 업데이트이자 첫번째 업데이트입니다. 주요 Javascript 엔진에서 이러한 기능의 구현은 현재 진행 중입니다.
ECMAScript 6 언어의 전체 사양은 ES6 표준을 참조하세요.
ES6는 다음의 새로운 기능을 포함합니다.
- arrows
- classes
- enhanced object literals
- template strings
- destructuring
- default + rest + spread
- let + const
- iterators + for..of
- generators
- unicode
- modules
- module loaders
- map + set + weakmap + weakset
- proxies
- symbols
- subclassable built-ins
- promises
- math + number + string + array + object APIs
- binary and octal literals
- reflect api
- tail calls
ECMAScript 6 기능
Arrows
화살표는 =>
문법을 사용하는 함수 단축어이며 문법적으로 C#, Java 8 and CoffeeScript에 있는 관련된 기능과 유사하다. 그들은 함수 구문 블록 본문 뿐만 아니라 함수식의 값을 반환하는 구문 본문 둘다 지원한다. 함수와 달리 화살표는 주변 코드와 동일한 ‘lexical this
‘를 공유한다.
1 | // Expression bodies |
자세한 정보: MDN Arrow Functions
클래스 (Classes)
ES6 클래스는 prototype 기반의 OO 패턴을 넘어 직관적이다. 단일의 편리한 선언적 폼을 갖는다는 것은 클래스 패턴을 더 쉽게 이용할 수 있도록 하며 상호운용성을 독려한다. 클래스는 prototype 기반의 상속(inheritance), super call, instance and static methods and constructors을 지원한다.
1 | class SkinnedMesh extends THREE.Mesh { |
더 자세한 정보: MDN Classes
강화된 객체 리터럴 (Enhanced Object Literals)
객체 리터럴은 생성 시 prototype 설정, foo: foo
할당에 대한 약축, 메서드 정의, super calls 생성 그리고 함수식으로 속성 이름을 계산하는 것을 지원하도록 확장됩니다. 또한, 이러한 것들은 객체 리터럴과 클래스 선언을 더 가깝게 만들고, 객체 지향 디자인에서 동일한 편의성을 활용할 수 있게 합니다.
1 | var obj = { |
자세한 정보: MDN Grammar and types: Object literals
템플릿 문자열(Template Strings)
템플릿 문자열은 더 직관적으로 문자열을 구성하도록 하며 Perl, Python 그리고 이외의 언어에서 문자열 보간 기능(string interpolation features)과 유사합니다. 선택적으로, 문자 구성을 커스터마이징하거나 인젝션(Injection) 공격을 피하기 위해 또는 문자 컨텐츠에서 높은 수준의 데이터 구조를 구성하기 위해 태그를 추가할 수 있습니다.
1 | // Basic literal string creation |
자세한 정보: MDN Template Strings
Destructuring (비구조화)
배열이나 객체의 매칭을 지원하는 비구조화는 패턴 매칭을 통해 바인딩할 수 있도록 하며, 표준 객체 조회 foo["bar"]
와 유사한 비구조화는 찾을 수 없는 경우, undefined
값을 생성하는 fail-soft 입니다.
1 | // list matching |
더 자세한 정보: MDN Destructuring assignment
Default 파라미터 + Rest 파라미터 + Spread 연산자
Default 파라미터란 현재 실행중인 함수가 평가하는 기본 파라미터 값이며 함수 호출에서 배열을 연속적 인수(argurement)로 변환해고, 후행(trailing) 파라미터를 배열에 바인딩합니다. Rest 파라미터는 인수(argurements)
에 대한 필요성을 대체하고, 일반적인 경우들을 보다 직접적으로 다룹니다.
1 | // Default Parameter |
1 | // Rest Parameter |
1 | // Spread Operator |
자세한 정보: Default parameters, Rest parameters, Spread Operator
Let + Const
블럭 범위의 바인딩을 구성하며 let
은 새로운 var
, const
는 상수입니다. 정적 제한은 할당 전에 사용을 방지합니다.
1 | function f() { |
자세한 정보: let statement, const statement
Iterators + For..Of
Iterator objects
는 CLR IEnumerable 또는 Java Iterable과 유사한 커스텀 반복문(iteration)을 가능하게 합니다. for..in
을 for..of
를 사용한 사용자가 정의한 반복기 기반의 반복문으로 일반화합니다. 배열을 구현할 필요가 없으며 LINQ와 같은 지연(lazy) 디자인 패턴이 사용 가능하다.
1 | let fibonacci = { |
반복문은 이와 같은 duck 타입 인터페이스에 기초합니다. (오직 설명을 위해 TypeScript을 사용합니다.)
1 | interface IteratorResult { |
자세한 정보: MDN for…of
Generators
Generator는 function*
and yield
를 사용해 반복기 작성을 단순화 하고, 함수는 Generator 인스턴스를 반환하는 function *
로써 선언됩니다.. Generator는 추가적인 next
와 throw
를 포함하는 반복기의 서브타입(subtype)이며, Generator 안에서 다시 돌아가기 위한 값이 될 수 있다. 그러나 yield
는 값을 반환하기 위한 또는 던지기(throw) 하기 위한 수식 양식(form) 입니다.
주의: 또한 async
프로그래밍과 같이 await
도 사용 가능합니다. ES7의 await
제안을 봅시다.
1 | var fibonacci = { |
Generator 인터페이스는 (오직 설명을 위한 TypeScript type syntax를 사용했다):
1 | interface Generator extends Iterator { |
자세한 정보: MDN Iteration protocols
유니코드(Unicode)
문자열에서 새로운 유니코드 리터럴 폼과 코드 포인트를 다루기 위한 새로운 RegExp u
모드 뿐만 아니라 21bit 코드 포인트 레벨에서 문자열을 처리하기 위한 새로운 API 를 포함하는 모든 유니코드를 지원하기 위한 논-블로킹 추가입니다. 이러한 추가는 Javascipt에서 세계적인 어플리케이션 구축을 지원합니다.
1 | // same as ES5.1 |
자세한 정보: MDN RegExp.prototype.unicode
Modules
컴포넌트 정의를 위한 모듈을 위한 언어 수준에서 지원하며 인기있는 Javascript 모듈 로더(AMD, CommonJS)가 패턴을 코드화합니다. 런타임 실행은 호스트가 정의한 기본 로더에 의해 정의되고, 암시적 비동기 모델입니다. - 요청된 모듈들이 처리되고 사용가능해질 때까지 어떠한 코드도 실행되지 않는다.
1 | // lib/math.js |
1 | // app.js |
1 | // otherApp.js |
몇 가지 추가적인 기능으로는 export default
과 export *
이 있다.
1 | // lib/mathplusplus.js |
1 | // app.js |
자세한 정보: import statement, export statement
Module Loaders
Module Loader가 지원하는 것들:
- 동적 로딩 (Dynamic loading)
- 상태 격리 (State isolation)
- 글로벌 네임스페이스 격리 (Global namespace isolation)
- 컴파일 훅 (Compilation hooks)
- 중첩된 가상화 (Nested virtualization)
기본 모듈 로더가 구성되어 있을 수 있으며 새로운 로더가 격리 또는 제한된 실행구문 안에서 코드를 불러오고 평가할 수 있도록 구성될수 있습니다.
1 | // Dynamic loading – ‘System’ is default loader |
Map + Set + WeakMap + WeakSet
공통된 알고리즘을 위한 효율적인 데이터 구조이며 WeakMaps은 누수(leak)로부터 자유로운 object-key 구조의 side tables을 제공합니다.
1 | // Sets |
자세한 정보: Map, Set, WeakMap, WeakSet
Proxies
Proxy는 호스트 객체에 사용 가능한 모든 동작 범위를 가진 객체를 생성할 수 있다. 가로채기(interception), 객체 가상화(object virtualization), 로깅/프로파일링(logging/profiling) 등에 대해 사용할 수 있습니다.
1 | // Proxying a normal object |
1 | // Proxying a function object |
모든 런타임 수준의 메타 작업을 사용 가능한 트랩이 있다.
1 | var handler = |
자세한 정보: MDN Proxy
Symbols
Symbol은 객체 상태에 접근 제어를 가능하게 하며 속성에 (ES5에서와 같이 ) string
또는 symbol
로 키를 지정할 수 있습니다. Symbol은 새로운 원시(primitive) 타입입니다. 선택적으로 description
파라미터를 디버깅에서 사용합니다. - 속성의 일부분은 아닙니다. Symbol은 고유하지만 Object.getOwnPropertySymbols
와 같은 reflection 기능을 통해 노출되기 때문에 비공개가 아니다.
1 | var MyClass = (function() { |
자세한 정보: MDN Symbol
Subclassable Built-ins
ES6에서는 Array
, Date
그리고 DOM Element
와 같은 내장 기능(built-in)을 서브클래싱할 수 있으며 현재 Ctor
라는 이름의 함수에 대한 객체 구조는 두가지 측면으로 사용한다.
- 특정 행위를 설치하기 위한
Ctor[@@create]
를 객체에 배치하기 위해 호출한다. - 새로운 인스턴스에 초기화하기 위한 constructor를 선언한다.
알려진 @@create
symbol은 symbol.create
를 통해 사용가능하고, 내장 기능들은 현재 암죽적으로 스스로의 @@create
를 노출합니다.
1 | // Pseudo-code of Array |
Math + Number + String + Array + Object APIs
핵심적인 수학 라이브러리, 배열, 변환 헬퍼, 문자열 헬퍼 그리고 복사를 위한 Object.assign를 포함해 많은 새로운 라이브러리 추가.
1 | Number.EPSILON |
자세한 정보: Number, Math, Array.from, Array.of, Array.prototype.copyWithin, Object.assign
Binary and Octal Literals
binary(2진법)의 (b
) 와 octal(8진법)의 (o
)에 대해 두 개의 새로운 숫자 리터럴 폼이 추가되었다.
1 | 0b111110111 === 503 // true |
Promises
Promise는 비동기 프로그래밍 라이브러리이며 미래에 가능하도록 하는 일급 표현(representation)이며, 현존하는 많은 Javascript 라이브러리에서 사용되고 있다.
1 | function timeout(duration = 0) { |
자세한 정보: MDN Promise
Reflect API
객체에 대한 런타임 수준의 메타 작업을 노출하는 전체 reflection API. Reflect API는 실제로 Proxy API의 반대이고, proxy 트랩으로서 같은 메타 작업에 따르는 콜들은 만들도록 해준다.
1 | const duck = { |
자세한 정보: MDN Reflect
Tail Calls
tail 포지션의 콜(call)은 스택이 무제한으로 증가하지 않도록 보장합니다. 무제한 입력에 대한 재귀 알고리즘을 안전하게 만듭니다.
1 | function factorial(n, acc = 1) { |