ECMAScript6

ES6은 어떻게 탄생했나?


Created by 손찬욱 / chanuk.son

ECMAScript6

ECMAScript Harmony

ES2015

JavaScript의 탄생

Brendan Eich (브랜든 아이크) 개발

1996년 3월 Netscape Navigator 2.0에서 JavaScript 지원

1996년 8월 Internet Explorer 3.0에서 JScript 지원

JavaScript를 널리 보급하자

표준화라... 어렵다

1996년 12월 ECMA에 표준등록을 위한 스펙 전달

ECMA-262, ECMAScript

1997년 6월 1'st Edition (ES1)

1998년 6월 2'nd Edition (ES2)

1999년 12월 3'rd Edition (ES3)

정규식, try/catch, ...

대다수 브라우저에서 ES3을 지원

이제 진정한 업계 표준

ECMAScript4

이제 좀 혁신적인 것을 만들자

Classes, Module system, Generators and iterators, Destructuring assignment, etc, ...

이게 무슨 JavaScript 야? 절라 복잡하자너

있는 것부터 잘하자! ECMAScript 3.1 워킹그룹

ES 4 VS ES 3.1

ECMAScript 4 지연

ECMAScript 4 is dropped

사실상 IE가 표준

두 그룹의 잡업을 합치기로 결정

ECMAScript Harmony

2008년 가을.

코드네임 ECMAScript Harmony 발표

ES4의 완성된 스펙을 ES5로 지정

ES4 나머지 스펙은 ECMAScript Harmony로 진행

2009년 12월. ES5 표준 발표. 두둥~!

ECMAScript 3.1 기반, No New Syntax

Strict mode, JSON, property define, ...

2015년 6월 ES6의 최종안인 ES2015를 발표 두둥~!

외국인도 열광하고

한국인들도 열광하고

도대체 ES6이 뭐길래?


복잡해진 웹애플리케이션 개발에 적합한 스펙


Classes, Module system, Reflect, Promise, Proxy, Generators and iterators, Destructuring assignment, etc, ...

더불어...

강력한 지원군

JSX로 변환해야하는 김에 ES6도 함께 지원한다

TypeScript를 써야하는 나도 ES6을 지원한다

잠깐 살펴보는

ES2015

Arrow Function

JavaScript에게 this 란?

호출 시점에 따라 this가 달라진다

ES6 이전의 함수

selfFunction.prototype.bind 없인 못살아

var obj = {
  print: function() {},
  printAll: function(args) {
    var self = this;
    args.forEach(function(v) {
       self.print(v);	// this는?
    });
  }
}

obj.print() // this is obj

ES6의 Arrow function

(파라미터)=>{함수 본체}

self 없이, 간결히 사용할수 있다

var obj = {
  print: function() {
  },
  printAll: function() {
    args.forEach((v) => this.print(v));
  }
}

arrow function을 감싸는 외부 scope를 사용

Class & inheritance

ES5의 Class와 inheritance 구현 방법

Object.create와 prototype을 이용

// 생성자
function Parent(name){
  this._name = name;
}

Parent.prototype = Object.create(null, {
	constructor: {
		value: Parent
	},
	say: {
		value: function() {
		  return 'My name is ' + this._name;
		}
	}
});

ES5의 Class와 inheritance 구현 방법 (계속)


// 생성자
function Child(name) {
  Parent.apply(this, arguments);	// 상위클래스 생성자 호출
}

Child.prototype = Object.create(Parent.prototype, {
  constructor: {
    value: Child
  },

  say: {
    value: function() {
    	// 상위클래스 메소드 호출
	var superClassPrototype =  Object.getPrototypeOf(this.constructor.prototype);
	return '[Child] ' + superClassPrototype.say.call(this);
    }
  }
});

ES6의 class와 inheritance

class, constructor, extends, super

class Parent {
	// 생성자
	constructor(name) {
		this._name = name;
	}
	say() {
		return 'My name is ' + this._name;
	}
}

class Child extends Parent {
	// 생성자
	constructor(name) {
		super(name);
	}
	say() {
		return '[Child] ' + super.say();
	}
}

Modules

JavaScript에게 전역 영역이란?

복잡한데 좀 쪼개서 사용할수 없을까?

쪼갠걸 재사용할수는 없을까?

독립적인 실행영역(scope)이 있고, 정의하고 사용하는 모듈이 필요함

ES6 이전의 module 구현 방법

  • IIFE : Immediately-Invoked Function Expression
  • (function(window) {
      // 결과를 윈도우에 import
      window.math = math;
    })(window);
  • AMD : requireJs
  • define(function() {
    	return math;
    });
    require( ["math"], function(math) {
    });
  • CommonJS : node
  • // math라는 이름으로 export
    exports.math = math;
    // 사용시에는 require
    var math = require("./math").math;
  • UMD : IIFE + AMD + CommonJS

ES6의 module 구현 방법

export와 import를 이용

// 모듈을 생성할 때
// lib/math.js
export function sum(x, y) {
  return x + y;
}
export var pi = 3.141593;
// 모듈을 사용할 때
import * as math from "lib/math";
alert("2π = " + math.sum(math.pi, math.pi));
alert("2π = " + sum(pi, pi));

Promise

이벤트의 순차적 실행 or 애니메이션의 순차적 진행

ES6 이전의 비동기식 프로그래밍 구현 방법

비동기 로직의 순차적 실행

callback hell

async1(function(input, result1) {
  async2(function(result2) {
    async3(function(result3) {
      async4(function(result4) {
        async5(function(output) {
            // do something with output
        });
      });
    });
  });
})

ES6 이전의 비동기식 프로그래밍 구현 방법 (계속)

Q, jQuery.Defferred 와 같은 라이브러리 사용

에러처리, 순서 보장

Q.fcall(async1)
.then(async2)
.then(async3)
.then(async4)
.then(function (output) {
    // do something with output
})
.catch(function (error) {
    // Handle any error from all above steps
})
.done();

ES6의 Promise 구현 방법

Promise 객체를 이용

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

그 외 개발의 편의성

  • Default parameter
  • Enhanced Object literals
  • Template string
  • The destructuring assignment
  • The spread operator

The Default parameter

기본값 지정

function test(name = "son", job, age = 20) {
	job = job || "programmer";

	// "son" 20 "programmer"
    	console.log(name, job, age);
}

Enhanced Object literals

객체 생성시, 동적으로 키 할당하기

var str = "name";

// ES6 이전
var obj = { };
obj["first" + str] = "son";
console.log(es6obj); // { "firstname" : "son" }

// ES6
var es6obj = { [“first” + str] : “son” };
console.log(es6obj); // { "firstname" : "son" }

Template string

템플릿 기능을 지원

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

// Hello son, how are you today?
console.log(`Hello ${name}, how are you ${time}?`);

The Destructuring assignment

한꺼번에 지정하기

var [a3, b3, c3 = "기본값"] = [1,2];
console.log(a3); // 1
console.log(b3); // 2
console.log(c3); // "기본값"

The spread operator (...)

데이터를 펼쳐서 지정하기

function test(a,b,c, ...args) {
   console.log(a,b,c); // 1, 10, 8
   console.log(args); // ["abc", "efg"]
}

test(...[1,10,8, "abc", "efg"]);

그렇다면, 지금 ES6을 사용할수 있나?

지원 브라우저는... 불가능

tranpiler(transcompiler)를 이용시... 가능


Proxy, own property를 제외하고는 모두 사용가능

http://kangax.github.io/compat-table/es6/

Reference

감사합니다.


BY 손찬욱 / chanuk.son