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 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);
}
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, 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
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);