JavaScript์ ES๋?, ES5/ES6 ๋ฌธ๋ฒ ์ฐจ์ด
๐จJavaScript
๐ป JavaScript์ ES๋?
1996๋ ์ ECMA(European Computer Manufacturers Association) International์ด๋ผ๋ ํ์ค ์กฐ์ง์ ๋ชจ๋ โโ๋ธ๋ผ์ฐ์ ๊ณต๊ธ์ ์ฒด๊ฐ ๊ตฌํํ ์ ์๋ ECMAScript(ES)๋ผ๋ ํ์ค ์ฌ์์ ๋ง๋ค์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ Javascript๋ ES์ ๊ฐ์ฅ ์ ์๋ ค์ง ๊ตฌํ์ด๋ฉฐ ActionScript(Macromedia/Adobe Systems)์ JScript(Microsoft)๋ ES์ ๋ค๋ฅธ ๊ตฌํ์ ๋๋ค.
ES์ ๋ฒ์ ๋ชฉ๋ก:
ํ์ฌ๊น์ง ES๋ 9๊ฐ์ ๋ฒ์ ์ ์ถํํ์ผ๋ฉฐ ์ต์ ๋ฒ์ (9๋ฒ์งธ ๋ฒ์ )์ 2018๋ ์ ์ถํ๋์์ต๋๋ค.
- ES1 1997
- ES2 1998
- ES3 1999
- ES4 ํฌ๊ธฐ
- ES5 2009
- ES6 2015
- ES7 2016
- ES8 2017
- ES9 2018
ECMA Script์ ์ฒ์ ์ธ ๊ฐ์ง ๋ฒ์ (ES1, ES2, ES3)์ ๋งค๋ ์ ๋ฐ์ดํธ๋๋ ๋ฐ๋ฉด, ES4๋ ์ ์น์ ๋ถ์ผ์น๋ก ์ธํด ์ถ์๋์ง ์์์ต๋๋ค. 10๋ ํ, ES5๋ ๊ฒฐ๊ตญ ๋ช ๊ฐ์ง ์ถ๊ฐ ๊ธฐ๋ฅ๊ณผ ํจ๊ป ์ถ์๋์์ต๋๋ค.
๐ปES5/ES6 ๋ฌธ๋ฒ ์ฐจ์ด
ECMAScript 5(ES5P) | ECMAScript 6(ES6) |
ECMA ์คํฌ๋ฆฝํธ๋ Ecma International์์ ์ ์ํ ์ํ ๋ฑ๋ก๋ ์คํฌ๋ฆฝํ ์ธ์ด ์ฌ์์ ๋๋ค. ๊ฐ์ ๊ฒ์ ๋ค์ฏ ๋ฒ์งธ ํ์ ES5๋ก ์๋ ค์ ธ ์์ต๋๋ค. | ECMA ์คํฌ๋ฆฝํธ๋ Ecma International์์ ์ ์ํ ์ํ ๋ฑ๋ก๋ ์คํฌ๋ฆฝํ ์ธ์ด ์ฌ์์ ๋๋ค. ๊ฐ์ ๊ฒ์ ์ฌ์ฏ ๋ฒ์งธ ํ์ ES6์ผ๋ก ์๋ ค์ ธ ์์ต๋๋ค. |
2009๋ ์ ๋์ ๋์์ต๋๋ค. | 2015๋ ์ ๋์ ๋์์ต๋๋ค. |
๋ฌธ์์ด, ์ซ์, ๋ถ์ธ, null ๋ฐ ์ ์๋์ง ์์ ๊ธฐ๋ณธ ๋ฐ์ดํฐ ์ ํ์ ์ง์ํฉ๋๋ค. | ES6์๋ JavaScript ๋ฐ์ดํฐ ์ ํ์ ๋ช ๊ฐ์ง ์ถ๊ฐ ์ฌํญ์ด ์์ต๋๋ค. ๊ณ ์ ๊ฐ์ ์ง์ํ๊ธฐ ์ํด ์๋ก์ด ๊ธฐ๋ณธ ๋ฐ์ดํฐ ์ ํ '๊ธฐํธ'๋ฅผ ๋์ ํ์ต๋๋ค. |
var ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ณ์๋ฅผ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ํ ๊ฐ์ง๋ฟ์ ๋๋ค. | let ๋ฐ const ๋ณ์๋ฅผ ์ ์ํ๋ ๋ ๊ฐ์ง ์๋ก์ด ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. |
ES6์ ๋นํด ์ฑ๋ฅ์ด ๋ฎ์ต๋๋ค. | ES5๋ณด๋ค ์ฑ๋ฅ์ด ๋์ต๋๋ค. |
๊ฐ์ฒด ์กฐ์์ ES5์์ ์๊ฐ์ด ๋ง์ด ๊ฑธ๋ฆฝ๋๋ค. | ๊ฐ์ฒด ์กฐ์์ ES6์์ ์๊ฐ์ด ๋ ๊ฑธ๋ฆฝ๋๋ค. |
ES5์์ function ๋ฐ return ํค์๋๋ ๋ชจ๋ ํจ์๋ฅผ ์ ์ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค. | ํ์ดํ ํจ์๋ ํจ์๋ฅผ ์ ์ํ๊ธฐ ์ํด function ํค์๋๊ฐ ํ์ํ์ง ์์ ES6์ ๋์ ๋ ์๋ก์ด ๊ธฐ๋ฅ์ ๋๋ค. |
ES6๋ณด๋ค ๋ ๋์ ๋ฒ์์ ์ปค๋ฎค๋ํฐ ์ง์์ ์ ๊ณตํฉ๋๋ค. | ES5๋ณด๋ค ์ ์ ๋ฒ์์ ์ปค๋ฎค๋ํฐ ์ง์์ ์ ๊ณตํฉ๋๋ค. |
ECMAScript 6 ์ ์ถ๊ฐ๋ ๊ธฐ๋ฅ
Arrows
Arrows(ํ์ดํ) ํจ์๋ => ๋ฌธ๋ฒ์ ์ฌ์ฉํ๋ ์ถ์ฝํ ํจ์์ ๋๋ค. C#, Java 8, CoffeeScript์ ํด๋น ๊ธฐ๋ฅ๊ณผ ๋ฌธ๋ฒ์ ์ผ๋ก ์ ์ฌํฉ๋๋ค. Arrows๋ ํํ์์ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฐํํ๋ ํํ์ ๋ณธ๋ฌธ(expression bodies)๋ฟ๋ง ์๋๋ผ ์ํ ๋ธ๋ญ ๋ณธ๋ฌธ(statement block bodies)๋ ์ง์ํฉ๋๋ค. ํ์ง๋ง ์ผ๋ฐ ํจ์์ ์์ ์ ํธ์ถํ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค๋ dynamic this์ ๋ฌ๋ฆฌ arrows ํจ์๋ ์ฝ๋์ ์์ ์ค์ฝํ(lexical scope)๋ฅผ ๊ฐ๋ฆฌํค๋ lexical this๋ฅผ ๊ฐ์ง๋๋ค.
var evens = [2, 4, 6, 8,];
// Expression bodies (ํํ์์ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋จ)
var odds = evens.map(v => v + 1); // [3, 5, 7, 9]
var nums = evens.map((v, i) => v + i); // [2, 5, 8, 11]
var pairs = evens.map(v => ({even: v, odd: v + 1})); // [{even: 2, odd: 3}, ...]
// Statement bodies (๋ธ๋ญ ๋ด๋ถ๋ฅผ ์คํ๋ง ํจ, ๋ฐํ์ ์ํด์ return์ ๋ช
์)
nums.forEach(v => {
if (v % 5 === 0)
fives.push(v);
});
// Lexical this
// ์ถ๋ ฅ๊ฒฐ๊ณผ : Bob knows John, Brian
var bob = {
_name: "Bob",
_friends: ["John, Brian"],
printFriends() {
this._friends.forEach(f =>
console.log(this._name + " knows " + f));
}
}
printFriends() ํจ์์ ์๋ธ๋ฃจํด์ ๋ค์๊ณผ ๋ฌธ๋ฒ์ ๋์ผํ๊ฒ ๋์ํฉ๋๋ค.
this._friends.forEach(function (f) {
console.log(this._name + " knows " + f));
}.bind(this));
Classes
ES6 ํด๋์ค๋ ํฌ๋กํ ํ์ ๊ธฐ๋ฐ ๊ฐ์ฒด์งํฅ ํจํด์ ๋ ์ฝ๊ฒ ์ฌ์ฉํ ์ ์๋ ๋์ฒด์ฌ์ ๋๋ค. ํด๋์ค ํจํด ์์ฑ์ ๋ ์ฝ๊ณ ๋จ์ํ๊ฒ ์์ฑํ ์ ์์ด์ ์ฌ์ฉํ๊ธฐ๋ ํธํ๊ณ ์ํธ์ด์ฉ์ฑ๋ ์ฆ๊ฐ๋ฉ๋๋ค.
class SkinnedMesh extends THREE.Mesh {
constructor(geometry, materials) {
super(geometry, materials);
this.idMatrix = SkinnedMesh.defaultMatrix();
this.bones = [];
this.boneMatrices = [];
//...
}
update(camera) {
//...
super.update();
}
get boneCount() {
return this.bones.length;
}
set matrixType(matrixType) {
this.idMatrix = SkinnedMesh[matrixType]();
}
static defaultMatrix() {
return new THREE.Matrix4();
}
}
Enhanced Object Literals
ES6์์ ๊ฐ์ฒด ๋ฆฌํฐ๋ด์ ์ ์ธ๋ฌธ์์ ํ๋กํ ํ์ ์ค์ , foo: foo ์ ์ธ์ ์ํ ๋จ์ถ ํ๊ธฐ๋ฒ, ๋ฉ์๋ ์ ์, super ํด๋์ค ํธ์ถ ๋ฐ ๋์ ์์ฑ๋ช ์ ์ง์ํ๋๋ก ํฅ์ ๋์์ต๋๋ค. ๊ทธ์ ๋ฐ๋ผ ๊ฐ์ฒด ๋ฆฌํฐ๋ด ๋ฐ ํด๋์ค ์ ์ธ์ด ๋ ๋ฐ์ ๋์ด์ ธ, ๊ฐ์ฒด๊ธฐ๋ฐ ์ค๊ณ๊ฐ ๋ ํธ๋ฆฌํด์ก์ต๋๋ค.
var obj = {
// __proto__
__proto__: theProtoObj,
// ‘handler: handler’์ ๋จ์ถ ํ๊ธฐ
handler,
// Methods
toString() {
// Super calls
return "d " + super.toString();
},
// Computed (dynamic) property names
[ 'prop_' + (() => 42)() ]: 42
};
Template Strings
Template Strings(ES6 ๋ถํฐ๋ Template literals๋ผ ๋ถ๋ฆ)๋ ๋ฌธ๋ฒ์ ์ผ๋ก ๋ ํธํ๊ฒ string์ ์์ฑํ ์ ์๊ฒ ํฉ๋๋ค. ์ด๋ Perl, Python ๋ฑ์ ๋ฌธ์์ด ๋ณด๊ฐ(string interpolation)๊ณผ ์ ์ฌํฉ๋๋ค. Tagged template literals๋ ์ธ์ ์ ๊ณต๊ฒฉ ๋ฐฉ์ด ํน์ ๋ฌธ์์ด๋ก ๋ถํฐ ์์ ๋ฐ์ดํฐ ๊ตฌ์กฐ์ฒด ์ฌ์กฐ๋ฆฝ ๋ฑ์ ์ํด string ์์ฑ์ ์ปค์คํฐ๋ง์ด์ง์ด ๊ฐ๋ฅํ๊ฒ๋ ํด์ค๋๋ค.
// 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);
Destructuring
Destructuring๋ ๋ฐฐ์ด๊ณผ ๊ฐ์ฒด์ ํจํด ๋งค์นญ์ ํตํ ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ์ ์ ๊ณตํฉ๋๋ค. Destructuring๋ ํ ๋น ์คํจ์ ์ ์ฐํ๋ฉฐ, ์คํจ ์ undefined ๊ฐ์ด ์๋ํ ๋น ๋ฉ๋๋ค. ๋ํ foo["bar"]์ ๊ฐ์ด ๊ฐ์ฒด์ ์์ฑ ๊ฐ๋ ์๋์ผ๋ก ๊ฒ์ํ์ฌ ๋ฐ์ธ๋ฉํด์ค๋๋ค.
// list matching
var [a, , b] = [1,2,3];
// object matching
var { op: a, lhs: { op: b }, rhs: c }
= getASTNode()
// object matching ๋จ์ถ ํ๊ธฐ
// binds `op`, `lhs` and `rhs` in scope
var {op, lhs, rhs} = getASTNode()
// parameter์์๋ ์ฌ์ฉ ๊ฐ๋ฅ
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;
Default + Rest + Spread
ํ๋ผ๋ฏธํฐ์ ๊ธฐ๋ณธ ๊ฐ์ ์ค์ ํ ์ ์์ต๋๋ค.
function f(x, y=12) {
// y is 12 if not passed (or passed as undefined)
return x + y;
}
f(3) // 15
๊ฐ๋ณ์ธ์๋ฅผ ์ฌ์ฉ๊ฐ๋ฅํ๋ฉฐ, ๋ฐฐ์ด๋ก ์นํ์์ผ ์ค๋๋ค. Rest parameters๋ arguments ๋ณด๋ค ์ง๊ด์ฑ์ ์ ๊ณตํฉ๋๋ค.
function f(x, ...y) {
// y is an Array ["hello", true]
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
๋ธ๋ก ์ ํจ ๋ฒ์๋ฅผ ๊ฐ๋ ์๋ก์ด ๋ณ์ ์ ์ธ ๋ฐฉ๋ฒ์ ์ง์ํฉ๋๋ค. let์ var์ ์ ์ฌํ๊ฒ ๋์ํฉ๋๋ค. const๋ ์ฌํ ๋น ๋ฐ ์ฌ์ ์ธ์ด ๋ถ๊ฐ๋ฅํฉ๋๋ค.
function f() {
{
let x;
{
// okay, block scoped name
const x = "sneaky";
// error, const
x = "foo";
}
// error, already declared in block
let x = "inner";
}
}
var์ ์ ํจ ๋ฒ์๋ ์ ์ฒด ์ธ๋ถ ํจ์๊น์ง์ด์ง๋ง let์ ๋ณ์๋ฅผ ์ ์ธํ ๋ธ๋ก๊ณผ ๊ทธ ๋ด๋ถ ๋ธ๋ก๋ค์์ ์ ํจํฉ๋๋ค.
function varTest() {
var x = 31;
if (true) {
var x = 71; // same variable!
console.log(x); // 71
}
console.log(x); // 71
}
function letTest() {
let x = 31;
if (true) {
let x = 71; // different variable
console.log(x); // 71
}
console.log(x); // 31
}
function varTest() {
if (true) {
var x = 71;
console.log(x); // 71
}
console.log(x); // 71
}
function varTest() {
let x = 71;
if (true) {
console.log(x); // 71
}
console.log(x); // 71
}
function varTest() {
if (true) {
let x = 71;
console.log(x); // 71
}
console.log(x); // Uncaught ReferenceError: x is not defined
}
Iterators + For…Of
Iterator ๊ฐ์ฒด๋ CLR์ IEnumerable ํน์ Java์ Iterable์ฒ๋ผ ์ฌ์ฉ์ ์ ์์ ๋ฐ๋ณต์ ๊ฐ๋ฅํ๊ฒ ํด์ค๋๋ค. for..of ๋ฐ๋ณต๋ฌธ์ด ES6์์ ์ถ๊ฐ ๋์์ผ๋ฉฐ for..in ๋ฐ๋ณต๋ฌธ๊ณผ ๋ฌ๋ฆฌ iterator ๊ธฐ๋ฐ์ ์ปฌ๋ ์ ์ ์ฉ ๋ฐ๋ณต๋ฌธ์ ๋๋ค. for in ๋ฐ๋ณต๋ฌธ๊ณผ์ ์ฐจ์ด์ ์ for in vs for of 503๋ฅผ ์ฐธ๊ณ ํ์ธ์.
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); // 1, 2, 3, 5, 8, ...987
}
Iteration์ ์๋์ duck-type ์ธํฐํ์ด์ค๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํฉ๋๋ค.
interface IteratorResult {
done: boolean;
value: any;
}
interface Iterator {
next(): IteratorResult;
}
interface Iterable {
[Symbol.iterator](): Iterator
}
Generators
Generators๋ function*์ yield ํค์๋๋ฅผ ์ด์ฉํ์ฌ iterator ์ ์ธ์ ๋จ์ํ๊ฒ ์์ฑํ ์ ์๊ฒ ๋์์ค๋๋ค. function*๋ก ์ ์ธํ ํจ์๋ Generator ๊ฐ์ฒด๋ฅผ ๋ฐํํฉ๋๋ค. Generators๋ iterator์ ํ์ ํ์ ์ด๋ฉฐ next์ throw ๋ฉ์๋๋ฅผ ๊ฐ์ง๊ณ ์์ต๋๋ค. ์ด ๋ฉ์๋๋ค๋ก ์ธํด yield ํค์๋๋ก ๋ฐํ๋ ๊ฐ์ ๋ค์ generator์ ์ฃผ์ ๊ฑฐ๋ ์์ธ์ฒ๋ฆฌ๋ฅผ ํ ์ ์๊ฒ ๋์์ต๋๋ค.
์ฐธ๊ณ : ํด๋น ํค์๋๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ‘await’ ๊ฐ์ ๊ธฐ๋ฅ์ด ๊ฐ๋ฅํ๊ฒ๋ ๊ธฐ๋ฐ์ด ๋์์ต๋๋ค. ES7์ await ์ ์์ 67๋ฅผ ์ฐธ๊ณ ํ์ธ์.
var fibonacci = {
[Symbol.iterator]: function*() {
var pre = 0, cur = 1;
for (;;) {
[pre, cur] = [cur, pre + cur];
yield cur;
}
}
}
for (var n of fibonacci) {
// truncate the sequence at 20
if (n > 20)
break;
console.log(n); // 1, 2, 3, 5, 8, 13
}
function* gen(){
yield* ["a", "b", "c"];
}
var a = gen();
a.next(); // { value: "a", done: false }
a.next(); // { value: "b", done: false }
a.next(); // { value: "c", done: false }
a.next(); // { value: undefined, done: true }
generator ์ธํฐํ์ด์ค๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
interface Generator extends Iterator {
next(value?: any): IteratorResult;
throw(exception: any);
}
Unicode
์์ ํ ์ ๋์ฝ๋๋ฅผ ์ง์ํ๊ธฐ ์ํด ๋ฌธ์์ด์ ์๋ก์ด ์ ๋์ฝ๋ ๋ฆฌํฐ๋ด๊ณผ ์ ๊ทํํ์์ u ๋ชจ๋๊ฐ ์ถ๊ฐ๋์์ต๋๋ค. ๋ํ 21๋นํธ ํ์๊น์ง ์ฒ๋ฆฌํ๊ธฐ ์ํ ์ ๊ท API๊ฐ ์ถ๊ฐ๋์์ต๋๋ค. ์ด ์ถ๊ฐ๋ ๊ธฐ๋ฅ์ JavaScript๋ก ๊ธ๋ก๋ฒ ์ฑ์ ๋ง๋ค ์ ์๋๋ก ์ง์ํฉ๋๋ค.
// same as ES5.1
"๐ ฎท".length == 2
// new RegExp behaviour, opt-in ‘u’
"๐ ฎท".match(/./u)[0].length == 2
// new form
"\u{20BB7}" == "๐ ฎท" == "\uD842\uDFB7"
// new String ops
"๐ ฎท".codePointAt(0) == 0x20BB7
// for-of iterates code points
for(var c of "๐ ฎท") {
console.log(c); // ๐ ฎท
}
Modules
์ธ์ด ์ฐจ์์์ ์ปดํฌ๋ํธ ์ ์๋ฅผ ์ํ ๋ชจ๋์ ์ง์ํฉ๋๋ค. ์ ๋ช ํ JavaScript ๋ชจ๋ ๋ก๋๋ค(AMD, CommonJS)์ ํจํด์ ์ ์ฉ์์ผฐ์ต๋๋ค. ๋ฐํ์ ๋์์ ํธ์คํธ์ ์ ์๋ ๊ธฐ๋ณธ ๋ก๋์ ์ํด ์ ์๋ฉ๋๋ค. ๋ฌต์์ ๋น๋๊ธฐ ํํ๋ก ์๊ตฌ๋๋ ๋ชจ๋๋ค์ด ์ ์์ ์ผ๋ก ๋ก๋๋๊ธฐ ์ ๊น์ง ์ฝ๋๊ฐ ์คํ๋์ง ์์ต๋๋ค.
// lib/math.js
export function sum(x, y) {
return x + y;
}
export var pi = 3.141593;
// app.js
import * as math from "lib/math";
console.log("2π = " + math.sum(math.pi, math.pi)); // 2π = 6.283186
// otherApp.js
import {sum, pi} from "lib/math";
console.log("2π = " + sum(pi, pi)); // 2π = 6.283186
export default์ export * ๋ฌธ๋ฒ๋ ์ ๊ณตํฉ๋๋ค.
// lib/mathplusplus.js
export * from "lib/math";
export var e = 2.71828182846;
export default function(x) {
return Math.log(x);
}
// app.js
import ln, {pi, e} from "lib/mathplusplus";
console.log("2π = " + ln(e)*pi*2);
Module Loaders
Module Loaders๋ ๋ค์์ ์ง์ํฉ๋๋ค.
- ๋์ ๋ก๋(Dynamic loading)
- ์ํ ๊ฒฉ๋ฆฌ(State isolation)
- ์ ์ญ ๋ค์์คํ์ด์ค ๊ฒฉ๋ฆฌ(Global namespace isolation)
- ์ปดํ์ผ ํ (Compilation hooks)
- ์ค์ฒฉ ๊ฐ์ํ(Nested virtualization)
๊ธฐ๋ณธ์ผ๋ก ์ฌ์ฉํ ๋ชจ๋ ๋ก๋๋ฅผ ์ค์ ํ ์ ์์ผ๋ฉฐ, ๋ก๋๋ฅผ ์๋ก ์์ฑํ์ฌ ๊ฒฉ๋ฆฌ๋๊ฑฐ๋ ์ ํ๋ ๋งฅ๋ฝ์์ ์ฝ๋๋ฅผ ๋ก๋ํ ์ ์์ต๋๋ค.
// ๋์ ๋ก๋ฉ – ‘System’ is default loader
System.import('lib/math').then(function(m) {
console.log("2π = " + m.sum(m.pi, m.pi));
});
// ์คํ ์๋๋ฐ์ค ์์ฑ – new Loaders
var loader = new Loader({
global: fixup(window) // replace ‘console.log’
});
loader.eval("console.log('hello world!');");
// ๋ชจ๋ ์บ์ ์ง์ ์กฐ์
System.get('jquery');
System.set('jquery', Module({$: $})); // WARNING: not yet finalized
Map + Set + WeakMap + WeakSet
์ผ๋ฐ ์๊ณ ๋ฆฌ์ฆ์ ์ํ ํจ์จ์ ์ธ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ ๊ณตํฉ๋๋ค. WeakMap๊ณผ WeakSet๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ก ๋ถํฐ ์์ ๋กญ๊ฒ ํด์ค๋๋ค. ์ด๋ค ๋ด ์ ์ฅ๋ ๊ฐ์ฒด์ ๋ค๋ฅธ ์ฐธ์กฐ๊ฐ ์๋ ๊ฒฝ์ฐ, garbage collection ๋ ์ ์์ต๋๋ค.
// 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 });
wm.size // undefined (์ฌ์ฉ๋ ๊ณณ์ด ์๊ธฐ ๋๋ฌธ)
Proxies
ํ๋ก์(Proxy)๋ฅผ ์ฌ์ฉํ๋ฉด ํธ์คํธ ๊ฐ์ฒด์ ๋ค์ํ ๊ธฐ๋ฅ์ ์ถ๊ฐํ์ฌ ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. interception, ๊ฐ์ฒด ์ถ์ํ, ๋ก๊น /์์ง, ๊ฐ ๊ฒ์ฆ ๋ฑ์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
// 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!';
// Proxying a function object
var target = function () { return 'I am the target'; };
var handler = {
apply: function (receiver, ...args) {
return 'I am the proxy';
}
};
var p = new Proxy(target, handler);
p() // 'I am the proxy';
let validator = {
set: function(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
}
// The default behavior to store the value
obj[prop] = value;
}
};
let person = new Proxy({}, validator);
person.age = 100;
console.log(person.age); // 100
person.age = 'young'; // Throws an exception
person.age = 300; // Throws an exception
proxy์ handler๊ฐ ๊ฐ์ง ์ ์๋ ํธ๋ฉ(trap)๋ค์ ๋๋ค.
var handler =
{
get:...,
set:...,
has:...,
deleteProperty:...,
apply:...,
construct:...,
getOwnPropertyDescriptor:...,
defineProperty:...,
getPrototypeOf:...,
setPrototypeOf:...,
enumerate:...,
ownKeys:...,
preventExtensions:...,
isExtensible:...
}
Symbols
์ฌ๋ณผ(Symbol)์ ๊ฐ์ฒด ์ํ์ ์ ๊ทผ ์ ์ด๋ฅผ ๊ฐ๋ฅํ๊ฒ ํฉ๋๋ค. Symbol์ ์๋ก์ด ์์ ํ์ ์ผ๋ก ์ด๋ฆ ์ถฉ๋์ ์ํ ์์ด ์์ฑ(property)์ ํค(key)๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ต์ ํ๋ผ๋ฏธํฐ์ธ description๋ ๋๋ฒ๊น ์ฉ๋๋ก ์ฌ์ฉ๋๋ฉฐ ์๋ณ ์ฉ๋๋ ์๋๋๋ค. Symbol์ ๊ณ ์ (unique)ํ๋ฉฐ, Object.getOwnPropertySymbols์ ๊ฐ์ reflection ๊ธฐ๋ฅ๋ค๋ก ์ ๊ทผํ ์ ์๊ธฐ ๋๋ฌธ์ private ํ์ง ์์ต๋๋ค(for in๋ Object.keys()๋ก๋ ์ ๊ทผ ๋ถ๊ฐ).
var map = {};
var a = Symbol('a');
map[a] = 123;
map["b"] = 456;
console.log(map[a]); // 123
console.log(map["b"]); // 456
for (let key in map) {
console.log(key); // b
}
Object.keys(map); // ["b"]
Subclassable Built-ins
ES6์์ Array, Date, DOM Element ๊ฐ์ด ๋ด์ฅ ๊ฐ์ฒด๋ค์ ์์์ด ๊ฐ๋ฅํฉ๋๋ค. ๊ฐ์ฒด ์์ฑ ์ ํธ์ถ๋๋ Ctor ํจ์๋ ๋ค์์ 2๋จ๊ณ๋ฅผ ๊ฐ์ง๋๋ค.(๋๋ค ๊ฐ์์ ์ผ๋ก ์คํ)
- ๊ฐ์ฒด ํ ๋น์ ์ํด Ctor[@@create] ํธ์ถํ์ฌ
- ์๋ก์ด ์ธ์คํด์ค์ ์์ฑ์๋ฅผ ํธ์ถํด ์ด๊ธฐํ ์งํ
์์๋ค์ถ์ด @@create ์ฌ๋ณผ์ Symbol.create๋ฅผ ํตํด ๋ง๋ค์ด์ก์ต๋๋ค.
// 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
Math + Number + String + Array + Object APIs
core Math ๋ผ์ด๋ธ๋ฌ๋ฆฌ, Array ์์ฑ helper, String helper, ๋ณต์ฌ๋ฅผ ์ํ Object.assign ๋ฑ ๋ง์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ์ถ๊ฐ๋์์ต๋๋ค.
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].find(x => x == 3) // 3
[1, 2, 3].findIndex(x => x == 2) // 1
[1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2]
["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) })
Binary and Octal
2์ง๋ฒ (b), 8์ง๋ฒ (o) numeric ๋ฆฌํฐ๋ด ํ์์ด ์ถ๊ฐ๋์์ต๋๋ค.
0b111110111 === 503 // true
0o767 === 503 // true
Promises
Promise๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. Promise๋ ๋ฏธ๋์ ์์ฑ๋๋ ๊ฐ์ ๋ํ๋ด๋ ์ผ๊ธ ๊ฐ์ฒด์ ๋๋ค. Promise๋ ํ์กดํ๋ ๋ง์ JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์ฌ์ฉ๋๊ณ ์์ต๋๋ค.
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)]);
})
Reflect API
Reflection API๋ ๋ฐํ์ ์ ๊ฐ์ฒด์ ๋ํด ์์ ์ ์ํํ ์ ์์ต๋๋ค. ํ๋ก์ ํธ๋ฉ(proxy traps)์ ๊ฐ์ ๋ฉํ ํจ์๋ค์ ๊ฐ์ง๊ณ ์์ต๋๋ค. Reflection์ ํ๋ก์๋ฅผ ๊ตฌํํ๋๋ฐ ์ ์ฉํฉ๋๋ค.
class Greeting {
constructor(name) {
this.name = name;
}
greet() {
return `Hello ${name}`;
}
}
function greetingFactory(name) {
return Reflect.construct(Greeting, [name], Greeting);
}
greetingFactory('a'); // Greeting {name: "a"}
Tail Calls
๋ง์ง๋ง์ ํธ์ถ๋๋ ํจ์๊ฐ ํธ์ถ ์คํ์ด ์ด๊ณผ๋๊ฒ ํ์ง ์์ต๋๋ค. ์ฌ๊ท ์๊ณ ๋ฆฌ์ฆ์ ๋งค์ฐ ํฐ ์ ๋ ฅ ๊ฐ์์๋ ์์ ํ๊ฒ ๋ง๋ญ๋๋ค.
function factorial(n, acc = 1) {
'use strict';
if (n <= 1) return acc;
return factorial(n - 1, n * acc);
}
// ํ์ฌ ๋๋ถ๋ถ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ง์์ ์คํ ์ค๋ฒํ๋ก์ฐ๊ฐ ์ผ์ด๋์ง๋ง,
// ES6์์๋ ์
๋ ฅ ๊ฐ์ด ์ปค๋ ์์ ํ๋ค
factorial(100000);
๐ป์ถ์ฒ ๋ฐ ์ฐธ๊ณ ์๋ฃ
https://www.greycampus.com/blog/programming/java-script-versions
Java Script Versions
ECMAScript is a widely used standard script language derived mainly from JavaScript. Look into the article to understand the new features for various versions that released after 2009, almost ten years after ES4's abandonment.
www.greycampus.com
https://www.geeksforgeeks.org/difference-between-es5-and-es6/
Difference between ES5 and ES6 - GeeksforGeeks
A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.
www.geeksforgeeks.org
ES6 ๋ฌธ๋ฒ ์ ๋ฆฌ
Vue ๊ณต๋ถ๋ฅผ ํ๋ค๊ฐ… ES6 ๋ฌธ๋ฒ์ ์๊ณ ๊ณต๋ถ๋ฅผ ํด์ผ ํ ๊ฒ ๊ฐ์ ๋ฒ์ญ์ ์งํํด๋ณด์์ต๋๋ค. (ํด์ผํ ๊ฒ์ด ์์ผ ๋ง๋์? ใ ใ ์ฌ๋ฌ๋ถ ๋ค๊ฐ์ด ๊ทธ๋ฅ jquery ์์๋ค ใ ใ ) ์ค๋ฒ์ญ ํน์ ์์ ํด์ผ ๋ ๊ฒ ์ด ์
jsdev.kr