Upload
yongwoo-jeon
View
1.543
Download
3
Embed Size (px)
Citation preview
ECMAScript 6(2015) 전용우
ECMAScript 4 이후ECMAScript 4에서 대규모 변화가 발생(Class, Packages, Namespace, Type Annotations…)
원활하게 진행되지 않아서 멈춤(Adobe는 이미 ES4을 기준으로 AC3을 만듬)
ECMAScript 3에서 몇 가지를 추가하고 개선하여 3.1 발표 (ECMAScript 5으로 부름)
ES3.1(5) + ES4 = ECMAScript Harmony = ECMAScript 6(ECMA.next의 일부)
공식 명칭은 ECMAScript 2015
ES 2015 Goals
Goals for the sixth edition include providing better support for
large applications,
library creation, and for
use of ECMAScript as a compilation target for other languages.
ecma-262_edition_6_03-17-15-releasecandidate3-rev36markup.pdf p.18
신규 특징들
Class
function Point(x,y){ this.x = x; this.y = y; } Point.staticMethod = function(){ return 'classy'; } Point.prototype.toString = function(){ return '(' + this.x + ', ' + this.y + ')'; }
class Point { constructor(x, y) { this.x = x; this.y = y; } static staticMethod() { return 'classy'; } toString() { return '(' + this.x + ', ' + this.y + ')'; } get prop() { return 'getter'; } set prop(value) { console.log('setter: '+value); } }
class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } toString() { return super.toString() + ' -‐ '; } }
특징
• 클래스의 타입은 함수이긴 하지만 Point()와 같이 호출 안됨
• Class는 hoist되지 않음.
Symbol
var ERROR = 1; var UPDATE = 2;
function something(type){ if(type===ERROR){ // error logic }else if(type===UPDATE){ // update logic } }
something(ERROR); something(1); // ?
var obj = {}; obj[UPDATE] = function(){ return 'bar'; } console.log(obj[UPDATE]()); // bar
const ERROR = Symbol(); const UPDATE = Symbol();
function something(type){ if(type===ERROR){ // error logic }else if(type===UPDATE){ // update logic } }
something(ERROR); something(Symbol()); // not working
const UPDATE = Symbol(); var obj = { [UPDATE]() { return 'bar'; } }; console.log(obj[FOO]()); // bar
WeakMap
var handleElement = {}; function setter(ele){ ele.dataset.key = "random"; handleElement[ele.dataset.key] = ele; }
function getter(ele){ if(ele.dataset.key){ ele = handleElement[ele.dataset.key]; }else{ //... } }
key객체가 삭제되면 WeakMap 객체내부의 값도 삭제된다.
var wm = new WeakMap(); wm.set(ele,"some"); wm.get(ele);
Module• CommonJS Modules 과 Asynchronous Module
Definition (AMD)을 사용.
• CommonJS처럼 쉽게 쓸 수 있고 자동으로 의존성 관리
• AMD처럼 비동기로 로딩이 가능하고 모듈 로딩을 설정
• 아쉽게도, 둘 중 어느 문법과도 호환 안됨.
var lib = require('package/lib'); define(['package/lib'], function( lib ){ console.log(lib); });
문법
//-‐-‐-‐-‐-‐-‐ lib.js -‐-‐-‐-‐-‐-‐ export const sqrt = Math.sqrt; export function square(x) { return x * x; } export function diag(x, y) { return sqrt(square(x) + square(y)); }
//-‐-‐-‐-‐-‐-‐ main.js -‐-‐-‐-‐-‐-‐ import { square, diag } from 'lib'; console.log(square(11)); // 121 console.log(diag(4, 3)); // 5
//-‐-‐-‐-‐-‐-‐ lib.js -‐-‐-‐-‐-‐-‐ import * as lib from 'lib'; export default function (obj) { lib.diag() }; export function each(obj, iterator, context) {...}
//-‐-‐-‐-‐-‐-‐ main.js -‐-‐-‐-‐-‐-‐ import _, { each } from 'underscore';
System.import('some_module') .then(some_module => { // Use some_module }) .catch(error => { ... });
Promise.all( ['module1', 'module2', 'module3']. map(x => System.import(x))) .then(([module1, module2, module3]) => { // Use module1, module2, module3 });
특징• Static module structure
• faster lookup
• variable checking
• [sweet.js]와 같이 macro을 위한 준비
• 타언어(LLJS, asm.js 같은)을 지원
lexical block scoping
function varTest() { var x = 31; if (true) { var x = 71; // same variable! console.log(x); // 71 } console.log(x); // 71 }
function varTest() { let x = 31; if (true) { let x = 71; // different variable! console.log(x); // 71 } console.log(x); // 31 }
특징
• 기존의 function scope에서 block scope임
• 같은 block scope에서 다시 정의 안되며 function body에서는 가능
• hoist 안됨.
Gerneratorfunction getJSON(url, callback) { var x = new XMLHttpRequest(); x.addEventListener("load",function(){ callback(null, x.responseText); }); x.open("GET", url); x.send(); }
console.log(‘foo');
getJSON("some.json",function(res){ console.log(res); });
console.log(‘bar');
run(function* (resume) { console.log('foo'); var res = yield getJSON("some.json", resume); console.log('bar'); console.log(res); });
function run(gen) { var iterable, resume; resume = function(err, retVal) { if (err) iterable.raise(err); iterable.next(retVal); }; iterable = gen(resume); iterable.next(); }
ES7
run(function* (resume) { console.log('foo'); var res = yield getJSON("some.json", resume); console.log('bar'); console.log(res); });
async function run (resume) { console.log('foo'); var res = await getJSON("some.json", resume); console.log('bar'); console.log(res); };
여전히 어색하고 불편한 문법[개선한 코드 조각]
Arrow function
var bob = { _name: "Bob", _friends: [], printFriends : function() { this._friends.forEach(function(f){ console.log(this._name + " knows " + f); }.bind(this)); } };
bob._friends.push(1); bob.printFriends();
var bob = { _name: "Bob", _friends: [], printFriends() { this._friends.forEach((f , i) => console.log(this._name + " knows " + f) ); } };
bob._friends.push(1); bob.printFriends();
Destructuring, Default parameter valuesfunction some(obj){ var a = obj.a; var b = obj.b; console.log(a,b); } some({a:1,b:2});
function some(index, ax){ if(!index){ index = 1; } if(!index){ ax = 0; } console.log(index); console.log(ax); }
function some(obj){ var [a,b] = obj; console.log(a,b); } some({a:1,b:2});
function some(index = 1, ax = 0){ console.log(index); console.log(ax); }
Named parameters via destructuring
Entries.prototype.select = function (options) { if (options === undefined) options = {}; if (options.from === undefined) options.from = 0; if (options.to === undefined) options.to = this.length;
};
Entries.prototype.select = function ({ from = 0, to = this.length }) { if(from > 10 || to > 2){}; };
Proxy
실제 object을 수정하면 반응하지 않기 때문에 불편함.
var object = { foo: null }, proxy = new Proxy(object, { set: function(object, property, value, proxy) { object[property] = String(value).toUpperCase(); } });
proxy.foo = "a"; console.log(proxy.foo);
var object = { foo: null }; Object.observe(object, function(changes) { console.log("Changes: ", changes); });
object.foo = "bar";
ES7
Iteratorlet arr = [3, 5, 7]; arr.foo = "hello";
for (let i in arr) { console.log(arr[i],i); // logs "0", "1", "2", "foo" }
var helloWorld = new Words("Hello world"); for (var word of helloWorld) { console.log(word); } // Result: "Hello" // Result: "world"
for (let v of arr) { console.log(v); // logs "3", "5", "7" }
function Words(str) { this._str = str; }
Words.prototype[Symbol.iterator] = function() { var re = /\S+/g; var str = this._str; return { next: function() { var match = re.exec(str); if (match) { return {value: match[0], done: false}; } return {value: undefined, done: true}; } } };
기타• firefox의 예전 버전은 “@@iterator”로 메서드를 등록.
(17~36) • Nodelist에도 Symbol.iterator가 구현되어 있어 사용가능.
for (var node of document.querySelectorAll('a')) { console.log(node); }
ES 2015를 어떻게 대비할까?(개인적으로)
• 아직 쓸만한 수준은 아니여서 (우리나라 실정에) 바로 업무에 쓰지 못함.(모바일은 좀 빠를 수 있음)
• 언어를 개선했다기 보다 다양한 개념들이 있기 때문에 신규 언어에 가까워 자연스럽게 넘어가기란 쉽지 않음.(기존의 경험이 독이 되는 경우가 많을 것 같음)
• 이미 많은 해외 라이브러리는 Transpiler을 활용하여 개발
• CoffeeScript, TypeScript, Traceur, basel.io을 활용(with source maps)
• ECMAScript 7(201X)는 이미 진행 중
• http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts
• http://chimera.labs.oreilly.com/books/1234000001623/index.html
• https://leanpub.com/understandinges6/read/
• http://www.2ality.com/2014/08/es6-today.html
• http://www.2ality.com/2015/02/es6-classes-final.html
• http://www.2ality.com/2014/12/es6-symbols.html
• http://www.2ality.com/2014/09/es6-modules-final.html
• https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap
• https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let
• http://addyosmani.com/writing-modular-js/
• http://kangax.github.io/compat-table/es6/
• https://github.com/MaxArt2501/object-observe/blob/master/doc/index.md
• http://jakearchibald.com/2014/iterators-gonna-iterate/
• http://www.html5rocks.com/ko/tutorials/es6/promises/
• http://jakearchibald.com/2014/es7-async-functions/
• https://github.com/mozilla/task.js