[ES6]자바스크립트 ES6 2편

2018. 6. 23. 13:46javascript/Es6

[ES6]자바스크립트 ES6



Iterators + for....of 

for of문은 일반적으로 String, map, Uint8, Array, Set등에서 반복가능한 오브젝트들을 반복 시킬 때 사용했다. 하지만 예시와 같은 것들이 아니 더라도 우리가 직접 [Symbol.Iterators]를 만들어줘서 사용할 수 있다. 


let fibonacci = {
    [Symbol.iterator](){
        let val = 0, nextVal=1;
        return{
            next(){
                [val, nextVal] = [nextVal, val+nextVal];
                return {done:false, value:nextVal};
            }
        }
    }
};

for (i of fibonacci){
    if (i>1000) break;
    console.log(i);
}

위의 예시와 전혀 관계가 없지만 직접 iterator를 구현함으로 써 for....of문을 사용할 수 있다. 그리고 iterator는 이런식으로 구현되어있다. 

interface 
IteratorResult {
 done: boolean; value: any;
 } 
interface Iterator { 
next(): IteratorResult; 
} 
interface Iterable { 
[Symbol.iterator](): Iterator 

}

우리가 직접 적어준 코드에 next와 iterator의 return done과 value등이 있다. 


Generators

function*()과 yield를 사용해서 iterators를 조금 더 쉽게 표현할 수 있는 방법이다. Genrators는 iterators의 하위 타입이며 next와 throw를 갖고있다고한다. yield를 통해서 반환하고 다시 generator로 값을 전달해준다. 

 


const fibo = {
    [Symbol.iterator] : function *(){
        let val = 0, cur = 1;
            while(true){
            [val, cur] = [cur, cur + val];
            yield cur;
        }
    }
};

for (i of fibo){
    if (i>2000) break;
    console.log(i);
}

const generatorTest = function *() {
  yield 4;
  yield [1, 2, 3, 4];
  yield {a:"a", b:"b"};
  yield *(function *() {yield 7, yield 8})();
  yield function *() {yield 8, yield 9};
};
const b = generatorTest();
console.log(b.next());
console.log(b.next());
console.log(b.next());
console.log(b.next().value);
console.log(b.next().value);
const a = b.next().value();
console.log(a.next().value);
console.log(a.next().value);



Modules

우리가 프로그래밍을 하면서 외부에 만들어져있는 모듈들을 불러올 필요가 있을 때 가있다. 하지만 예전에는 require을 사용해서 외부 라이브러리를 불러왔다면 es6에서는 파이썬처럼 import 모듈이름 as 별명 from 같이 사용할 수 있다. 

export function sum(x, y) { return x + y; } 
export var pi = 3.141593;

import * as math from "lib/math";
console.log(math.sum(math.pi, math.pi));

이와 같은 단순한 export는 여러개의 값을 가져가서 쓸 수 있게 만들 때 쓰는 것이고 


export default  pi = 3.141593;

한개의 값만을 사용할 수 있을 때 쓰는 것이다. 주로 메인으로 사용될 것을 내보낸다. 



map, set, weakSet, weakMap 


자바스크립트 내에서 조금 더 편리하게 알고리즘 적인 요소를 사용하라고 map, set, weakSet, weakMap등을 제공하고 있다. 


map 


키값과 value값으로 표현할 수 있다. 


var map = new Map()
map.set("dog", "mungmung");
map.set("cat", "yaongyaong");
map.set("monkey", "UGGIGGI");

console.log(map.get("monkey"));


set 


value값만 입력하긴 하지만 중복된 값을 허용하지 않는다.

출력해보면 4만 한번나온다. 

let set = new Set();
set.add("1");
set.add("2");
set.add("3");
set.add("4");
set.add("4");
set.add("4");
set.add("4");

for (i of set){
console.log(i);
}


weakSet 


new WeakSet([iterable]) iterable객체가 전달되는 경우 모든 객체요소는 새로운 WeakSet에 추가됩니다.


Set과 달리 

1. WeakSet은 객체만의 컬렉션이며 모든 유형의 임의의 값이 아니다. 

2. 컬렉션 내 객체 참조는 약하게 유지됩니다. WeakSet 내 저장된 객체에 다른 참조가 없는 경우, 쓰레기 수집(garbage collection)될 수 있습니다.


var ws = new WeakSet();
var obj = {};
var foo = {};

ws.add(window);
ws.add(obj);

ws.has(window);
ws.has(foo);

ws.delete(window);
ws.has(window);

 WeakSet내에 객체는 오직 한번만 발생할 수 있습니다.  안에 값이 비어지게 된다면 가비지 컬렉션이 됩니다.  -> 메모리 절약할 수 있다. 


weakMap 


weakMap은 하나의 값만을 저장할 수 있고 this와 연관된 private 데이터를 조회할 수 있다. 이렇게 되면 모든 인스턴스가 하나의 WeakMap을 공유하게된다. 그리고 다른 객체 참조가 없는 경우 가비지 컬랙션이된다. 

let Person = function () {
let privateProps = new WeakMap();
class Person {
constructor(name) {
this.name = name;// this is public
privateProps.set(this, {age: 20}); // this is private
}
greet() {
// Here we can access both name and age
console.log(`name: ${this.name}, age: ${privateProps.get(this).age}`);
}
}
return Person;
}();
let joe = new Person('Joe');
joe.greet();



Symbol 


새로운 원시 타입 이름의 충돌없이 속성의 키로 사용할 수 있습니다.  for in이나 Object.key로 접근할 수 없다. 


let map = {}
let a = Symbol('a');
console.log(a);

map[a] = "abc"
map["b"] = "bbb"

console.log(map[a]);
console.log(map["b"]);

for (let key in map){
console.log(key);
}

Object.keys(map);


Tail Calls

마지막에 호출되는 함수가 스택을 초과해도 안정적이게 사용할 수 있다. 


function factorial(n){
if (n == 0) return 1;
return factorial(n-1)*n;
}

console.log(factorial(100));

값이 크면 stack overFlow가 발생하지만 너무 크면 여전힐 발생한다. 예전보다는 조금 더 안전하게 재귀함수를 돌릴 수 있는 것 같다.

'javascript > Es6' 카테고리의 다른 글

배열의 map 사용해보기  (0) 2018.11.19
[ES6]자바스크립트 ES6 Promise  (0) 2018.06.25
[ES6]자바스크립트 ES6 1편  (0) 2018.06.23