[Front] ECMA6 맛보기

ECMA6란

  • ECMAScript는 자바스크립트의 토대를 구성하는 스크립트 언어 명세이다
    Europen Computer Manufacturers Association의 약어

  • ECMAScript 6.0( ECMAScript 2015)이 2015년 6월 공표/ 현재 외국의 오픈소스들 중 다수가 ecma6로 개발
    (react, angular2등)

  • 우리나라는 좀 시일이 걸릴듯. 브라우저에서 점점 더 지원범위를 늘려가고 있음
    ES6 기반으로 애플리케이션을 개발할 경우 BabelJS를 통해 ES5로 컴파일할 수 있다

  • TypeScript는 ES6를 포함해 별도의 추가 기능을 포함한다

클래스 도입

기존에 프로토타입형식으로 선언하여 사용하던 OOP를 클래스 형태도 지원 할 수 있도록
하지만 근본적으로 자바스크립트가 클래스형식의 OOP를 지원하기 위해 만든 언어는 아니여서 성능적으로 좋지 않고 불안함.

// ES5

'use strict';

function User(name){
  this._name = name;
}

User.prototype = Object.create(null, {
  constructor: {
    value: User
  },

  say: {
    value: function() {
      return 'My name is ' + this._name;
    }
  }
});

var user = new User('Alice');
console.log(user.say()); // My name is Alice
// ES6

'use strict';

class User {
  constructor(name) {
    this._name = name;
  }

  say() {
    return 'My name is ' + this._name;
  }
}

var user = new User('Alice');
console.log(user.say()); // My name is Alice


블럭 스코프 Let

블락스코프

function f() {
  {
  
    let x;
    {
      // okay, block scoped name

      const x = "sneaky";
      // error, const

      x = "foo";
    }
    // error, already declared in block

    let x = "inner";
    
    var a = 3;
    if(true){
        let b = 3;
    }
    console.log(b);
    console.log(a);
  }
}

for of

  • for in은 객체의 프로토타입까지 모두 순회했다면
  • es6의 for of는 콜랙션의 유효값만 순회
  • Array, Map, Set, String, TypedArray, arguments 를 포함한 모든 iteralbe한 오브젝트에 사용 가능
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);
}

Arrow function

  • this에 대한 번거로움 해소
  • 자바8의 람다형식
// ES5

'use strict';

var ClickCounter = {
  _count: 0,

  start: function(selector) {
    var node = document.querySelector(selector);
    node.addEventListener('click', function(evt){
      this._count++;
    }.bind(this));
  }
};

ClickCounter.start('body');
// ES6

'use strict';

var ClickCounter = {
  _count: 0,

  start: function(selector) {
    var node = document.querySelector(selector);
    node.addEventListener('click', (evt)=>{
      this._count++;
    });
  }
};

ClickCounter.start('body');

Default + Rest + Spread

  • 기존의 x = x || 3 방식으로 초기화 하던 방식을 미리 초기화 할 수 있게 해줌
function f(x, y=12) {
  // y is 12 if not passed (or passed as undefined)

  return x + y;
}
f(3) == 15
  • 가변인수를 지원 해줌, arguments로 인자 순회를 할 필요가 없어짐
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

Destructuring

기존에 아예없던 기능. 패턴매칭을 통해 값을 바인딩 해줌 없으면 undefined.
여러 변수를 한번에 초기화 하는게 가능

// 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;

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}?`

// Construct an HTTP request prefix is used to interpret the replacements and construction

POST`http://foo.org/bar?a=${a}&b=${b}

     Content-Type: application/json
     X-Credentials: ${credentials}
     { "foo": ${foo},
       "bar": ${bar}}`(myOnReadyStateChangeHandler);

Generators

  • yield를 단순화 시키기 위해 function의 iterator를 사용 할 수 있도록 함
  • yield란 함수 중간에 값을 넘기거나 중지시키는것 (파이썬과 유사)
  • yield 키워드는 생성기 함수 (function* 또는 오래된 생성기 함수)를 중지하거나 재개하는데 사용
function* foo(){
  var index = 0;
  while (index <= 2) // when index reaches 3, 

                     // yield's done will be true 

                     // and its value will be undefined;

    yield index++;
}
var iterator = foo();
console.log(iterator.next()); // { value: 0, done: false }

console.log(iterator.next()); // { value: 1, done: false }

console.log(iterator.next()); // { value: 2, done: false }

console.log(iterator.next()); // { value: undefined, done: true }
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);
}
The generator interface is (using TypeScript type syntax for exposition only):

interface Generator extends Iterator {
    next(value?: any): IteratorResult;
    throw(exception: any);
}

module로딩 방식 개선

  • AMD, CommonJS의 영향을 받음
  • module을 export하고 import해서 사용 할 수 있게 해줌
    // app.js
    import * as math from "lib/math";
    alert("2π = " + math.sum(math.pi, math.pi));
    

Module loaders support:

  • Dynamic loading
  • State isolation
  • Global namespace isolation
  • Compilation hooks
  • Nested virtualization
// Dynamic loading – ‘System’ is default loader

System.import('lib/math').then(function(m) {
  alert("2π = " + m.sum(m.pi, m.pi));
});

// Create execution sandboxes – new Loaders

var loader = new Loader({
  global: fixup(window) // replace ‘console.log’

});
loader.eval("console.log('hello world!');");

// Directly manipulate module cache

System.get('jquery');
System.set('jquery', Module({$: $})); // WARNING: not yet finalized

Promises

비동기 방식에 쓰이는 방식. es6에서 정식지원 기존 angular의 $q에서 쓰이는 방식과 유사

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

Symbols

  • object에서 특이한 문법 형식으로 쓰임. 어떤 정보를 개체에 덧붙인다.
  • object의 고유값을 지정, 외부에서는 접근 할 수가 없음. object당 유일
  • 7번째 타입(type)

심볼은 다른 어떤 것과도 다른 것

심볼은 일단 생성되면 변경되지 않습니다. 심볼에는 속성을 부여할 수 없습니다 (만약 strict 모드에서 그런 시도를 하면 TypeError가 발생합니다). 심볼은 속성 이름으로 사용할 수 있습니다. 여기까지의 특성들은 모두 문자열과 유사합니다.

반면, 각 심볼은 고유합니다. 다른 심볼들과 구별됩니다 (같은 주석을 갖고 있더라도 다른 심볼입니다). 그리고 우리는 간단하게 새로운 심볼을 만들 수 있습니다. 여기까지의 특성들은 객체와 유사합니다.

ES6 심볼은 Lisp나 Ruby 같은 랭귀지의 좀 더 전통적인 심볼들과 비슷합니다. 하지만 랭귀지에 아주 밀접하게 통합되어 있지는 않습니다. Lisp 랭귀지의 경우 모든 식별자들은 심볼입니다. JS 랭귀지의 경우, 대부분의 식별자들과 속성 키(key)들은 여전히 문자열입니다. 심볼(Symbol)은 그냥 추가 옵션일 뿐입니다.

심볼에 관련된 주의사항이 있습니다. 랭귀지의 다른 요소들과 달리, 심볼은 문자열로 자동 변환되지 않습니다. 심볼을 다른 문자열에 이어붙이려고(concatenate)하면 TypeError가 발생합니다.

http://hacks.mozilla.or.kr/2015/09/es6-in-depth-symbols/

그 외

고정 공백 유니코드 지원

Map + Set + WeakMap + WeakSet 자료구조 지원

Proxies

Math + Number + String + Array + Object APIs에 다양한 매서드 추가

http://www.ecma-international.org/ecma-262/6.0/
http://202psj.tistory.com/803

ES6테스트하기 : http://www.es6fiddle.net/

Comments

comments powered by Disqus
comments powered by Disqus