2015-08-26

[ECMAScript 6] Symbol - 7번째 primitive type

  지금까지 자바스크립트에는 number, boolean, string, null, undefined, object의 6가지 타입밖에 없었다. 그래서 C의 enum 같은 타입이 필요하거나, 일종의 태깅 같은 것을 위해 고유한 값이 필요했을 경우 보통 number나 string 타입을 이용했다.

 하지만 ECMAScript 6에서는 이제 number나 string을 이용할 필요가 없다. ECMAScript 6에서는 새로운 타입인 Symbol 타입이 추가되었기 때문이다.

 Symbol 타입의 값은 Symbol 함수를 통해서만 생성할 수 있고, new를 통해서 만들 수 없다.

 Symbol 함수는 인자로 description을 받을 수도 있고, 아무 인자도 받지 않을 수도 있다. 이 인자는 실제로 생성되는 Symbol에 영향을 주지 않는다. 로깅 등을 위해서 toString 함수를 이용해 string으로 변환할 때, 반영되지만 이는 디버깅을 위해서고, 일반적으로 이 description을 이용할 일은 없다. 같은 description을 이용해 생성한 Symbol도 실제로는 다른 값을 가진다.


 이는 Symbol 타입이 unique함을 보장하기 때문이다. Symbol 타입은 immutability와 unique 함이 보장된다. number나 string도 immutability는 보장된다. 하지만 unique 함은 보장되지 않는다. 이것이 Symbol 타입과 number/string 타입과의 차이점이다.

 같은 Symbol을 가지고 오기 위해서는 생성한 Symbol을 전역 변수로 등록시키고 있어야 한다. 이것을 해주는 게 for 함수이다.

 Symbol.for() 함수는 key를 인자로 받는다. 이전에 같은 key로 생성한 Symbol이 있으면 그 Symbol을 돌려주고, 처음 받은 key면 새로운 Symbol을 생성하여, 저장한 뒤 돌려준다.

 주의해야 할 것은 Symbol.for(key) 함수는 이미 등록된 Symbol이 있을 경우만 그것을 가지고 올 수 있다는 것이다. 따라서 Symbol(description)을 이용해서 생성한 Symbol은 Symbol.for(key)를 이용해서 가지고 올 수 없다.

 이런 특징을 이용해서 아래와 같이 object의 private property를 만드는 것도 가능하다.


2015-08-25

[ECMAScript 6] block 안에서 함수 만들기

 JavaScript 함수 선언의 가장 큰 특징은 함수의 선언 위치에 상관없이 언제나 코드의 가장 위에서 함수를 선언한 것처럼 코드가 실행된다는 것이다. 따라서 아래와 같은 코드는

 사실은 아래와 같은 코드라고 보아도 된다.

 이를 function hoisting이라고 한다. 이 덕분에 함수 선언문보다 앞에서 함수를 사용할 수 있다. 하지만 함수 선언은 언제나 스코프의 가장 윗부분으로 hoisting 된다. 따라서 함수 안에서 선언된 함수는 함수 내에서 언제나 같은 함수를 의미했고, 특정 block 안에서는 다른 함수를 의미하도록 사용할 수 없었다.

 하지만 ECMAScript 6에서는 block 단위의 함수 선언을 허용한다.

 즉, 위와 같이 if block 안에서만 다른 값을 의미하도록 하는 것이 가능하다.

 하지만 아쉽게도 이는 아직 대부분 브라우저나 node.js에서는 구현되지 않았다. 따라서 블록 단위 함수 선언을 사용하려면 babel.js를 사용해야 한다.

2015-08-22

[ECMAScript 6] 함수 이름 가져오기

 자바스크립트는 두 가지 방식으로 함수를 선언할 수 있다.
 평범하게 방법은 함수를 선언하여 사용할 수도 있고, 익명함수를 만들어 사용할 수도 있다.

 ECMAScript 5까지는 어떻게 만들어지든 둘 사이에는 차이가 없었다. 만들 수 있는 위치나, 함수의 선언 및 할당이 실제로 이뤄지는 위치가 다르기는 하지만, 어쨌든 만들어지고 난 다음에 둘은 아무런 차이가 없었다.

 위와 같은 코드는 사실 아래와 같은 코드에 syntax sugar일 뿐이다.


 하지만 ECMAScript 6 이후로 둘은 name property라는 다른 점을 가진다. 첫 번째 방식으로 만든 함수는 named function이라고 불리며 name이라는 프로퍼티를 가진다. 반면에 두 번째 방식으로 만들어진 함수는 anonymous function이라고 불리며 길이가 0인 문자열("")을 name property로 가진다.

2015-08-11

[ECMAScript 6] fat arrow function

 fat arrow function(=>)는 ECMAScript 6에 추가된 익명 함수를 생성하는 새로운 방법이다. 기존의 함수를 만드는 것보다 짧게 함수를 만들 수 있다.

이는 다른 함수에 콜백으로 함수를 넘겨야 하는 경우 요긴하게 사용된다.

 하지만 단순히 길이가 짧다는 것만이 arrow function의 장점이 아니다. 오히려 중요한 특색은 arrow function은 thislexical scope에서 찾는다는 것이다.

 JavaScript 함수의 가장 큰 특징 중 하나는 this가 dynamic binding 된다는 것이다. 보통은 큰 문제가 되지 않지만, 메소드를 콜백으로 넘겨주어야 하는 경우나 메소드를 변수로 받을 경우 원하는 대로 돌아가지 않았다.


 ECMAScript 5에서는 Function에 bind 메소드가 추가되어 원하는 오브젝트를 this로 바인드 한 함수를 만들 수 있지만, 매번 이런 작업을 하는 것은 귀찮은 일이다. 이제 ECMAScript 6에서는 이런 경우에 =>을 이용하여 this가 lexical binding 된 함수를 만들면 된다.

2015-08-08

[TypeScript] Type guard - sum type 분리하기

 Type guard는 다른 언어에서 보기 힘든 TypeScript만의 독특한 기능으로, 타입 인트로스펙션을 통해 분기한 블록 안에서 해당 변수의 타입을 한정시켜주는 기능을 말한다.

 TypeScript를 사용하다 보면, 하나의 변수가 2개 이상의 타입일 가능성이 있는 경우가 자주 생긴다. TypeScript의 본질이 JavaScript이고 이는 동적 타입 언어이기 때문일 것이다. 이를 위해서 TypeScritp는 any 타입을 이용하거나, 조금 더 안전한 사용을 위해서 유니언 타입을 이용한다. 하지만 유니언 타입의 값은 그 값이 될 수 있는 모든 타입이 공통으로 가지는 함수와 프로퍼티만 이용할 수 있고, 모든 타입이 들어갈 수 있는 함수에만 사용 사용할 수 있다.
 이런 불편함을 없애기 위해서 나온 기능이 type guard이다.

 위의 코드처럼 여러 개의 타입이 될 수 있는 값을 사용하기 전에 인트로스펙션을 이용해서 타입을 확인하고 값을 사용하는 것은 JavaScript에서 볼 수 있는 흔한 패턴이다. 이렇게 타입을 확인하고 나면, 확인한 블록 안에서 그 값은 해당하는 타입이 되는 것이 type guard이다.

 하지만 아직 모든 인트로스펙션에 대해서 type guard가 적용되는 것은 아니다. 현재 type guard가 적용되는 경우는 인트로스펙션이 조건문에 들어가는 if 블록과 그에 따라오는 else 블록뿐이다.
위의 예제처럼 if 블록이 반드시 return 하여 그다음은 else 블록과 다를 바 없는 경우에는 type guard가 적용되지 않는다.

 게다가 모든 인트로스펙션이 가능한 것도 아니고, instanceof를 사용하는 경우와 typeof의 결과가 'number', 'string', 'boolean'이 되는 경우뿐이다. 그래서 underscore 등을 이용해서 타입 체킹을 하는 경우나 인트로스펙션 부분을 함수로 뺀 경우는 type guard가 동작하지 않는다. 이는 TypeScript 1.6에 계획된 type guard function이 들어오면 해결될 문제지만, 아직은 어쩔 수 없다.