The better things is coming
2015.03.01
waka.org, 김훈민
ES2015 Overview
“=>” 을 이용해서 함수를 축약 표현
함수가 존재하는 어휘 환경의 콘텍스트를 함수의 this에 자동 바인딩
Arrows function
var odds = evens.map(v => v + 1);

var nums = evens.map((v, i) => v + i);

var pairs = evens.map(v => ({even: v, odd: v + 1}));



nums.forEach(v => {

if (v % 5 === 0)

fives.push(v);

});



// Lexical this

var bob = {

_name: "Bob",

_friends: [],

printFriends() {

this._friends.forEach(f => console.log(this._name + " knows " + f) );

}

};
prototype을 이용한 OOP 패턴에 새로운 문법 설탕 제공
classes
class SkinnedMesh extends THREE.Mesh {

constructor(geometry, materials) {

super(geometry, materials);



this.idMatrix = SkinnedMesh.defaultMatrix();

this.bones = [];

this.boneMatrices = [];

//...

}

update(camera) {

//...

super.update();

}

static defaultMatrix() {

return new THREE.Matrix4();

}

}
__proto__ 설정, 변수 할당/메소드 선언 축약, 상위 객체 참조 등
enhanced object literals
var obj = {

// __proto__

__proto__: theProtoObj,

// Shorthand for ‘handler: handler’

handler,

// Methods

toString() {

// Super calls

return "d " + super.toString();

},

// Computed (dynamic) property names

[ 'prop_' + (() => 42)() ]: 42

};
multi-line string, 문자열 내 변수 값 바인딩
template strings
// Basic literal string creation

`In JavaScript 'n' is a line-feed.`



// Multiline strings

`In JavaScript this is

not legal.`



// String interpolation

var name = "Bob", time = "today";

`Hello ${name}, how are you ${time}?`



패턴 매칭을 이용한 변수, 값 바인딩
destructuring
// list matching

var [a, , b] = [1,2,3];



// object matching

var { op: a, lhs: { op: b }, rhs: c } = getASTNode();



// object matching shorthand

// binds `op`, `lhs` and `rhs` in scope

var {op, lhs, rhs} = getASTNode();



// Can be used in parameter position

function g({name: x}) {

console.log(x);

}

g({name: 5})



// Fail-soft destructuring

var [a] = [];

a === undefined;



// Fail-soft destructuring with defaults

var [a = 1] = [];

a === 1;
파라미터 기본 값 설정,
trailing parameter를 배열에 바인딩,
배열을 인자로 전달, 각 항목을 개별 파라미터에 바인딩 가능
default + rest + spread
function f(x, y=12) {

// y is 12 if not passed (or passed as undefined)

return x + y;

}



f(3) == 15;





function f(x, ...y) {

// y is an Array

return x * y.length;

}



f(3, "hello", true) == 6;





function f(x, y, z) {

return x + y + z;

}



// Pass each elem of array as argument

f(...[1,2,3]) == 6;
블럭 유효범위를 갖는 변수, 상수 선언
let + const
function f() {

{

let x;

{

// okay, block scoped name

const x = "sneaky";

// error, const

x = "foo";

}

// error, already declared in block

let x = "inner";

}

}





function f(x, y, z) {

return x + y + z;

}



// Pass each elem of array as argument

f(...[1,2,3]) == 6;
사용자 정의 열거 기능 정의 가능,
Symbol.iterator를 이용해서 기능 구현 후 for ..of로 사용
iterators + for ..of
let fibonacci = {

[Symbol.iterator]() {

let pre = 0, cur = 1;

return {

next() {

[pre, cur] = [cur, pre + cur];

return { done: false, value: cur }

}

}

}

}



for (var n of fibonacci) {

// truncate the sequence at 1000

if (n > 1000)

break;

console.log(n);

}
콘텍스트 밖으로 나갔다가 다시 들어갈 수 있는 함수
재진입시 본래 콘텍스트를 다시 복원
function*과 yield로 반복 작업 작성을 단순화
Generator
var fibonacci = {

[Symbol.iterator]: function*() {

var pre = 0, cur = 1;

for (;;) {

var temp = pre;

pre = cur;

cur += temp;

yield cur;

}

}

}



for (var n of fibonacci) {

// truncate the sequence at 1000

if (n > 1000)

break;

console.log(n);

}
Non-breaking additions to support full Unicode, including new Unicode literal form in
strings and new RegExp u mode to handle code points, as well as new APIs to process
strings at the 21bit code points level.
unicode
// same as ES5.1

"𠮷".length == 2



// new RegExp behaviour, opt-in ‘u’

"𠮷".match(/./u)[0].length == 2



// new form

“u{20BB7}”==“𠮷”==“uD842uDFB7”



// new String ops

"𠮷".codePointAt(0) == 0x20BB7



// for-of iterates code points

for(var c of "𠮷") {

console.log(c);

}
export, import 키워드를 이용해서 모듈을 작성 가능
modules
// lib/math.js

export function sum(x, y) {

return x + y;

}

export var pi = 3.141593;



// app.js

import * as math from "lib/math";

alert("2π = " + math.sum(math.pi, math.pi));





// lib/mathplusplus.js

export * from "lib/math";

export var e = 2.71828182846;

export default function(x) {

return Math.exp(x);

}



// app.js

import exp, {pi, e} from "lib/mathplusplus";

alert("2π = " + exp(pi, e));
동적 모듈 로딩,
네임스페이스 샌드박싱
module loaders
System.import(

['module1', 'module2'],

function (module1, module2) { // success

...

},

function (err) { // failure

...

}

);
새로운 Map, Set 자료구조 추가
Weak Reference를 갖는 WeakMap, WeakSet 추가
map + set + weakmap + weakset
// Sets

var s = new Set();

s.add("hello").add("goodbye").add("hello");

s.size === 2;

s.has("hello") === true;



// Maps

var m = new Map();

m.set("hello", 42);

m.set(s, 34);

m.get(s) == 34;



// Weak Maps

var wm = new WeakMap();

wm.set(s, { extra: 42 });

wm.size === undefined



// Weak Sets

var ws = new WeakSet();

ws.add({ data: 42 });

// Because the added object has no other references, it will not be held in the set
호스트 객체의 기본 동작(프로퍼티 검색/할당, 열거, 함수 호출… 등)에
개발자가 원하는 동작을 추가
proxies
// Proxying a normal object

var target = {};

var handler = {

get: function (receiver, name) {

return `Hello, ${name}!`;

}

};



var p = new Proxy(target, handler);

p.world === 'Hello, world!';
유일성, 불변성을 갖는 새로운 원시 타입
Symbol 객체는 symbol 데이터 타입을 래핑
symbols
var MyClass = (function() {



// module scoped symbol

var key = Symbol("key");



function MyClass(privateData) {

this[key] = privateData;

}



MyClass.prototype = {

doStuff: function() {

... this[key] ...

}

};



return MyClass;

})();



var c = new MyClass("hello")

c["key"] === undefined
Array, Date, DOM Element 같은 내장 객체를 서브 클래스화 할 수 있음
subclassable built-ins
// Pseudo-code of Array

class Array {

constructor(...args) { /* ... */ }

static [Symbol.create]() {

// Install special [[DefineOwnProperty]]

// to magically update 'length'

}

}



// User code of Array subclass

class MyArray extends Array {

constructor(...args) {
super(...args);
}

}



// Two-phase 'new':

// 1) Call @@create to allocate object

// 2) Invoke constructor on new instance

var arr = new MyArray();

arr[1] = 12;

arr.length == 2
라이브러리로 이용하던 promise가 표준 스펙으로 추가
promises
function timeout(duration = 0) {

return new Promise((resolve, reject) => {

setTimeout(resolve, duration);

})

}



var p = timeout(1000).then(() => {

return timeout(2000);

}).then(() => {

throw new Error("hmm");

}).catch(err => {

return Promise.all([timeout(100), timeout(200)]);

});
Math, Number, String, Object에 새로운 API 추가
Math + Number + String + Object APIs
Number.EPSILON

Number.isInteger(Infinity) // false

Number.isNaN("NaN") // false



Math.acosh(3) // 1.762747174039086

Math.hypot(3, 4) // 5

Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2



"abcde".includes("cd") // true

"abc".repeat(3) // "abcabcabc"



Array.from(document.querySelectorAll('*')) // Returns a real Array

Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior

[0, 0, 0].fill(7, 1) // [0,7,7]

[1,2,3].findIndex(x => x == 2) // 1

["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]

["a", "b", "c"].keys() // iterator 0, 1, 2

["a", "b", "c"].values() // iterator "a", "b", "c"



Object.assign(Point, { origin: new Point(0,0) });
꼬리 재귀 최적화 추가,
함수형 프로그래밍을 하는 데 있어 장애 요인이었던 스택 오버플로우에서 해방
tail calls
function factorial(n, acc = 1) {

'use strict';

if (n <= 1) return acc;

return factorial(n - 1, n * acc);

}



// Stack overflow in most implementations today,

// but safe on arbitrary inputs in ES6

factorial(100000);

감사합니다.

Es2015 Simple Overview

  • 1.
    The better thingsis coming 2015.03.01 waka.org, 김훈민 ES2015 Overview
  • 2.
    “=>” 을 이용해서함수를 축약 표현 함수가 존재하는 어휘 환경의 콘텍스트를 함수의 this에 자동 바인딩 Arrows function var odds = evens.map(v => v + 1);
 var nums = evens.map((v, i) => v + i);
 var pairs = evens.map(v => ({even: v, odd: v + 1}));
 
 nums.forEach(v => {
 if (v % 5 === 0)
 fives.push(v);
 });
 
 // Lexical this
 var bob = {
 _name: "Bob",
 _friends: [],
 printFriends() {
 this._friends.forEach(f => console.log(this._name + " knows " + f) );
 }
 };
  • 3.
    prototype을 이용한 OOP패턴에 새로운 문법 설탕 제공 classes class SkinnedMesh extends THREE.Mesh {
 constructor(geometry, materials) {
 super(geometry, materials);
 
 this.idMatrix = SkinnedMesh.defaultMatrix();
 this.bones = [];
 this.boneMatrices = [];
 //...
 }
 update(camera) {
 //...
 super.update();
 }
 static defaultMatrix() {
 return new THREE.Matrix4();
 }
 }
  • 4.
    __proto__ 설정, 변수할당/메소드 선언 축약, 상위 객체 참조 등 enhanced object literals var obj = {
 // __proto__
 __proto__: theProtoObj,
 // Shorthand for ‘handler: handler’
 handler,
 // Methods
 toString() {
 // Super calls
 return "d " + super.toString();
 },
 // Computed (dynamic) property names
 [ 'prop_' + (() => 42)() ]: 42
 };
  • 5.
    multi-line string, 문자열내 변수 값 바인딩 template strings // Basic literal string creation
 `In JavaScript 'n' is a line-feed.`
 
 // Multiline strings
 `In JavaScript this is
 not legal.`
 
 // String interpolation
 var name = "Bob", time = "today";
 `Hello ${name}, how are you ${time}?`
 

  • 6.
    패턴 매칭을 이용한변수, 값 바인딩 destructuring // list matching
 var [a, , b] = [1,2,3];
 
 // object matching
 var { op: a, lhs: { op: b }, rhs: c } = getASTNode();
 
 // object matching shorthand
 // binds `op`, `lhs` and `rhs` in scope
 var {op, lhs, rhs} = getASTNode();
 
 // Can be used in parameter position
 function g({name: x}) {
 console.log(x);
 }
 g({name: 5})
 
 // Fail-soft destructuring
 var [a] = [];
 a === undefined;
 
 // Fail-soft destructuring with defaults
 var [a = 1] = [];
 a === 1;
  • 7.
    파라미터 기본 값설정, trailing parameter를 배열에 바인딩, 배열을 인자로 전달, 각 항목을 개별 파라미터에 바인딩 가능 default + rest + spread function f(x, y=12) {
 // y is 12 if not passed (or passed as undefined)
 return x + y;
 }
 
 f(3) == 15;
 
 
 function f(x, ...y) {
 // y is an Array
 return x * y.length;
 }
 
 f(3, "hello", true) == 6;
 
 
 function f(x, y, z) {
 return x + y + z;
 }
 
 // Pass each elem of array as argument
 f(...[1,2,3]) == 6;
  • 8.
    블럭 유효범위를 갖는변수, 상수 선언 let + const function f() {
 {
 let x;
 {
 // okay, block scoped name
 const x = "sneaky";
 // error, const
 x = "foo";
 }
 // error, already declared in block
 let x = "inner";
 }
 }
 
 
 function f(x, y, z) {
 return x + y + z;
 }
 
 // Pass each elem of array as argument
 f(...[1,2,3]) == 6;
  • 9.
    사용자 정의 열거기능 정의 가능, Symbol.iterator를 이용해서 기능 구현 후 for ..of로 사용 iterators + for ..of let fibonacci = {
 [Symbol.iterator]() {
 let pre = 0, cur = 1;
 return {
 next() {
 [pre, cur] = [cur, pre + cur];
 return { done: false, value: cur }
 }
 }
 }
 }
 
 for (var n of fibonacci) {
 // truncate the sequence at 1000
 if (n > 1000)
 break;
 console.log(n);
 }
  • 10.
    콘텍스트 밖으로 나갔다가다시 들어갈 수 있는 함수 재진입시 본래 콘텍스트를 다시 복원 function*과 yield로 반복 작업 작성을 단순화 Generator var fibonacci = {
 [Symbol.iterator]: function*() {
 var pre = 0, cur = 1;
 for (;;) {
 var temp = pre;
 pre = cur;
 cur += temp;
 yield cur;
 }
 }
 }
 
 for (var n of fibonacci) {
 // truncate the sequence at 1000
 if (n > 1000)
 break;
 console.log(n);
 }
  • 11.
    Non-breaking additions tosupport full Unicode, including new Unicode literal form in strings and new RegExp u mode to handle code points, as well as new APIs to process strings at the 21bit code points level. unicode // same as ES5.1
 "𠮷".length == 2
 
 // new RegExp behaviour, opt-in ‘u’
 "𠮷".match(/./u)[0].length == 2
 
 // new form
 “u{20BB7}”==“𠮷”==“uD842uDFB7”
 
 // new String ops
 "𠮷".codePointAt(0) == 0x20BB7
 
 // for-of iterates code points
 for(var c of "𠮷") {
 console.log(c);
 }
  • 12.
    export, import 키워드를이용해서 모듈을 작성 가능 modules // lib/math.js
 export function sum(x, y) {
 return x + y;
 }
 export var pi = 3.141593;
 
 // app.js
 import * as math from "lib/math";
 alert("2π = " + math.sum(math.pi, math.pi));
 
 
 // lib/mathplusplus.js
 export * from "lib/math";
 export var e = 2.71828182846;
 export default function(x) {
 return Math.exp(x);
 }
 
 // app.js
 import exp, {pi, e} from "lib/mathplusplus";
 alert("2π = " + exp(pi, e));
  • 13.
    동적 모듈 로딩, 네임스페이스샌드박싱 module loaders System.import(
 ['module1', 'module2'],
 function (module1, module2) { // success
 ...
 },
 function (err) { // failure
 ...
 }
 );
  • 14.
    새로운 Map, Set자료구조 추가 Weak Reference를 갖는 WeakMap, WeakSet 추가 map + set + weakmap + weakset // Sets
 var s = new Set();
 s.add("hello").add("goodbye").add("hello");
 s.size === 2;
 s.has("hello") === true;
 
 // Maps
 var m = new Map();
 m.set("hello", 42);
 m.set(s, 34);
 m.get(s) == 34;
 
 // Weak Maps
 var wm = new WeakMap();
 wm.set(s, { extra: 42 });
 wm.size === undefined
 
 // Weak Sets
 var ws = new WeakSet();
 ws.add({ data: 42 });
 // Because the added object has no other references, it will not be held in the set
  • 15.
    호스트 객체의 기본동작(프로퍼티 검색/할당, 열거, 함수 호출… 등)에 개발자가 원하는 동작을 추가 proxies // Proxying a normal object
 var target = {};
 var handler = {
 get: function (receiver, name) {
 return `Hello, ${name}!`;
 }
 };
 
 var p = new Proxy(target, handler);
 p.world === 'Hello, world!';
  • 16.
    유일성, 불변성을 갖는새로운 원시 타입 Symbol 객체는 symbol 데이터 타입을 래핑 symbols var MyClass = (function() {
 
 // module scoped symbol
 var key = Symbol("key");
 
 function MyClass(privateData) {
 this[key] = privateData;
 }
 
 MyClass.prototype = {
 doStuff: function() {
 ... this[key] ...
 }
 };
 
 return MyClass;
 })();
 
 var c = new MyClass("hello")
 c["key"] === undefined
  • 17.
    Array, Date, DOMElement 같은 내장 객체를 서브 클래스화 할 수 있음 subclassable built-ins // Pseudo-code of Array
 class Array {
 constructor(...args) { /* ... */ }
 static [Symbol.create]() {
 // Install special [[DefineOwnProperty]]
 // to magically update 'length'
 }
 }
 
 // User code of Array subclass
 class MyArray extends Array {
 constructor(...args) { super(...args); }
 }
 
 // Two-phase 'new':
 // 1) Call @@create to allocate object
 // 2) Invoke constructor on new instance
 var arr = new MyArray();
 arr[1] = 12;
 arr.length == 2
  • 18.
    라이브러리로 이용하던 promise가표준 스펙으로 추가 promises function timeout(duration = 0) {
 return new Promise((resolve, reject) => {
 setTimeout(resolve, duration);
 })
 }
 
 var p = timeout(1000).then(() => {
 return timeout(2000);
 }).then(() => {
 throw new Error("hmm");
 }).catch(err => {
 return Promise.all([timeout(100), timeout(200)]);
 });
  • 19.
    Math, Number, String,Object에 새로운 API 추가 Math + Number + String + Object APIs Number.EPSILON
 Number.isInteger(Infinity) // false
 Number.isNaN("NaN") // false
 
 Math.acosh(3) // 1.762747174039086
 Math.hypot(3, 4) // 5
 Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2
 
 "abcde".includes("cd") // true
 "abc".repeat(3) // "abcabcabc"
 
 Array.from(document.querySelectorAll('*')) // Returns a real Array
 Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior
 [0, 0, 0].fill(7, 1) // [0,7,7]
 [1,2,3].findIndex(x => x == 2) // 1
 ["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"]
 ["a", "b", "c"].keys() // iterator 0, 1, 2
 ["a", "b", "c"].values() // iterator "a", "b", "c"
 
 Object.assign(Point, { origin: new Point(0,0) });
  • 20.
    꼬리 재귀 최적화추가, 함수형 프로그래밍을 하는 데 있어 장애 요인이었던 스택 오버플로우에서 해방 tail calls function factorial(n, acc = 1) {
 'use strict';
 if (n <= 1) return acc;
 return factorial(n - 1, n * acc);
 }
 
 // Stack overflow in most implementations today,
 // but safe on arbitrary inputs in ES6
 factorial(100000);

  • 21.