게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌22 - ECMAScript - 7년 전 등록 / 2년 전 수정

ESNext stage-2(Draft)

안녕하세요. 이번 시간에는 stage-3에 이어 stage-2에 대해 알아보겠습니다! 1~3년 내에 정식 스펙에 들어갈 만한 친구들입니다.

여기에 따르면 아직 브라우저에서 지원하는 것이 없습니다. @babel/preset-stage-2 typescript를 설치하면 이 기능들을 사용할 수 있습니다. class decorators는 정말 놀라운 변화입니다. 

다음 코드는 브라우저에서 동작하지 않으니 따라 치지는 마시고 눈으로만 보세요.

class decorators

리액트를 하셨던 분이라면 몇 번 보셨을텐데요. 클래스를 감싸는 함수를 만드는 방법입니다. HOC를 만들 때 가끔 이런 문법을 쓰는 것을 보신 적이 있을 겁니다.

function hello(msg) {
  return function(target) {
    target.hello = msg;
  };
}
function readonly(target, key, descriptor) {
  descriptor.writable = false;
  return descriptor;
}

@hello('안녕')
class ZeroCho {
  @readonly
  static name = 'zerocho';
}
ZeroCho.hello; // '안녕'
ZeroCho.name; // 'zerocho';
ZeroCho.name = 'babo'; // Error 발생

클래스와 속성 앞에 @로 시작하는 함수가 붙었죠? 이것들이 decorator입니다. 다음 줄에 나오는 클래스나 속성이 target으로 들어가고요. hello 함수를 보면 '안녕'이라는 글자를 받아서 target.hello에 그 글자를 대입합니다. 여기서의 target은 @hello 다음에 나오는 ZeroCho 클래스입니다.

readonly 함수를 보면 다음에 나오는 속성의 descriptor를 받아 writable을 false로 만들어주었습니다. 따라서 @readonly decorator 다음에 나오는 name 속성은 수정할 수 없습니다. 여기서의 target은 name 속성이 됩니다. descriptor은 name 속성의 descriptor인 것이고요.

function.sent

generator에서 function.sent 특수값을 사용할 수 있습니다. next의 인수로 전달된 값을 function.sent로 받는 것입니다.

var result;
function* generator() {
result = function.sent;
}
var iter = generator();
iter.next('tromple');
result === 'tromple'; // true

throw expressions

throw를 자유자재로 할 수 있습니다. 신나게 에러를 뱉어봅시다. 함수의 인자를 검사하거나 할 때 유용하게 쓸 수 있습니다.

a = a || throw 'a는 필수 인자입니다';
b = b && throw 'b는 거짓(falsy) 값이어야 합니다.'
function(c = throw 'c는 필수 인자입니다') { }
d = () => throw '무조건 에러'
e = e ? true : throw 'e는 참(truthy) 값이어야 합니다.'

물론 throw의 인자는 catch의 error로 전달됩니다.

Set methods

Set에 intersection(교집합), union(합집합), difference(차집합), symmetricDifference(대칭차집합), isDisjointFrom(교집합없음), isSubsetOf(부분집합), isSupersetOf(상위집합) 등 집합을 적용할 수 있는 개념들이 추가되었습니다. 매우 편하게 두 배열을 비교할 수 있게 되었습니다. 아래는 전부 true입니다.

var set = new Set([1, 2, 3]).intersection(new Set([2, 3, 4]));
set.size === 2 && set.has(2) && set.has(3);
var set = new Set([1, 2]).union(new Set([2, 3]));
set.size === 3 && set.has(1) && set.has(2) && set.has(3);
var set = new Set([1, 2, 3]).difference(new Set([3, 4]));
set.size === 2 && set.has(1) && set.has(2);
var set = new Set([1, 2]).symmetricDifference(new Set([2, 3]));
set.size === 2 && set.has(1) && set.has(3);
new Set([1, 2, 3]).isDisjointFrom([4, 5, 6]);
new Set([1, 2, 3]).isSubsetOf([5, 4, 3, 2, 1]);
new Set([5, 4, 3, 2, 1]).isSupersetOf([1, 2, 3])

Map.prototype.upsert

Map에 새로운 값을 추가하거나, 이미 존재하는 경우 새 값으로 수정하는 메서드인 upsert가 추가되었습니다. 아래 예시에서 a는 존재하므로 값이 2로 바뀌고 b는 존재하지 않으므로 값이 3으로 추가됩니다. 두 번째와 세 번째 인수인 함수는 각각 존재하면 2로 바꾸고, 존재하지 않으면 3으로 하라는 뜻입니다

const map = new Map([['a', 1]]);
map.upsert('a', it => 2, () => 3) === 2;
map.upsert('b', it => 2, () => 3) === 3;
Array.from(map).join() === 'a,2,b,3';

Array.isTemplateObject

템플릿 문자열 함수를 통해 생성된 배열인지를 알려주는 메서드입니다.

!Array.isTemplateObject([]) // true
Array.isTemplateObject((it => it)`a${1}c`); // true

Iterator Helpers

반복되는 값을 나타내는 Iterators에 여러 메서드가 추가됩니다. 배열.values()를 하면 Iterator 객체가 나오는데 여기에 배열 메서드들이 대다수 추가된다고 보시면 됩니다.

Record & Tuple

Record와 Tuple이 추가됩니다. 근래의 가장 큰 변화입니다.

const proposal = #{
  id: 1234,
  title: "Record & Tuple proposal",
  contents: `...`,
  // tuples are primitive types so you can put them in records:
  keywords: #["ecma", "tc39", "proposal", "record", "tuple"],
};

// Accessing keys like you would with objects!
console.log(proposal.title); // Record & Tuple proposal
console.log(proposal.keywords[1]); // tc39

// Spread like objects!
const proposal2 = #{
  ...proposal,
  title: "Stage 2: Record & Tuple",
};
console.log(proposal2.title); // Stage 2: Record & Tuple
console.log(proposal2.keywords[1]); // tc39

// Object functions work on Records:
console.log(Object.keys(proposal)); // ["contents", "id", "keywords", "title"]
const ship1 = #{ x: 1, y: 2 };
// ship2 is an ordinary object:
const ship2 = { x: -1, y: 3 };

function move(start, deltaX, deltaY) {
  // we always return a record after moving
  return #{
    x: start.x + deltaX,
    y: start.y + deltaY,
  };
}

const ship1Moved = move(ship1, 1, 0);
// passing an ordinary object to move() still works:
const ship2Moved = move(ship2, 3, -1);

console.log(ship1Moved === ship2Moved); // true
// ship1 and ship2 have the same coordinates after moving

자바스크립트의 Map, Set, Iterator에 점점 기능이 붙기 시작하네요. 다음 시간에는 stage-1에 대해서 알아보겠습니다!

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

아직 댓글이 없습니다.