https://www.sitepoint.com/es6-collections-map-set-weakmap-weakset/
ES6 Collections: Using Map, Set, WeakMap, WeakSet — SitePoint
MSDN's Kyle Pennell introduces the new ES6 collections Map, Set, WeakMap, WeakSet, explaining how and when to use these new data collection types.
www.sitepoint.com
- Collections
대부분의 프로그램 언어들은 데이터 콜렉션 타입을 갖고 있다.
파이썬의 경우 lists, utples, dictionaries 가 있고 자바는 lists, sets, maps, queues 그리고 루비는 hashes, arrays가 있다.
JS는 array만 있었는데 ES6 문법이 추가되면서 4가지 데이터 콜렉션 타입이 추가 되었다.
Map, Set WeakSet, WeakMap 이거 4가지이다. ES6를 지원하는 엔진에서만 돌아간다.
ES6 이전에 주로 키/벨류 쌍으로 저장하는 방법으로 Object를 사용하였는데 몇 가지 불리한 점이 있었다.
1. 키 값이 String으로 되어있어야 했다. 다른 타입으로 해도 돌아는 갔지만 내부적으로 다른 타입을 String으로 바꿨기 때문에 쓸데없는 작업을 해야했다.
2. 객체는 콜렉션으로 사용하려고 만든게 아니다. 반복하는 부분을 코드로 작성 해줘야 한다. 반복 할 때 각 프로퍼티에 딸린 프로토타입 프로퍼티도 같이 왔다 갔다 한다.
3. 객체 내부 메소드(constructor, toString, valueOf...)를 의식적으로 받아오지 않게 해야했다.
암튼 객체는 콜렉션이 아니었고 다른 언어의 콜렉션처럼 사용하는데 몇가지 제약이 있었다. 이걸 해결하기 위해 ES6에서 콜렉션 메서드들을 추가했다.
map을 만들고 사용하는 예제/
// 새로운 맵을 만든다.
const map = new Map();
// 맵에 set메서드로 키/값 쌍으로 넣는다. 앞에게 키 뒤에게 값
map.set('hobby', 'cycling');
// 새로운 객체 생성
const foods = { dinner: 'Curry', lunch: 'Sandwich', breakfast: 'Eggs' };
// 또 다른 새로운 빈 객체 생성
const normalfoods = {};
// 맵에 위의 2개 객체를 키/값으로 넣는다.
map.set(normalfoods, foods); // Sets two objects as key value pair
// for..of 반복문으로 map콜렉션의 키,값 을 반복시킨다.
for (const [key, value] of map) {
console.log(`${key} = ${value}`); // hobby = cycling [object Object] = [object Object]
}
// forEach 반복문으로 map콜렉션의 키, 값을 반복시킨다.
map.forEach((value, key) => {
console.log(`${key} = ${value}`); // hobby = cycling [object Object] = [object Object]
}, map);
// 맵에 있는 모든 키, 값을 지워버린다.
map.clear(); // Clears key value pairs
// 맵 사이즈 확인
console.log(map.size === 0); // True
*** 나중에 따로 정리 할거임 ***
foreach반복문 : 오직 Array 객체에서만 사용가능한 메서드( 반복문이 아니라 메서드임 )
for in 반복문 : 객체의 모든 열거 가능한 속성에 대해 반복
for of 반복문 : [Symbol.iterator] 속성을 가지는 컬렉션 전용 반복문
Set 콜렉션을 만들고 사용하는 예제
( map에 키/값을 집어넣을 때 set()을 사용하는데 여기서는 Set콜렉션이다. 다르다. 둘이. 뭐 이따구인지 모르겠다)
// 셋 컬렉션 생성
const planetsOrderFromSun = new Set();
// 셋 컬렉션에 값 집어넣음
planetsOrderFromSun.add('Mercury');
// 연속 넣기
planetsOrderFromSun.add('Venus').add('Earth').add('Mars');
// 컬렉션이 해당 값을 갖고 있는지 확인
console.log(planetsOrderFromSun.has('Earth')); // True
// 컬렉션에 해당 값 삭제
planetsOrderFromSun.delete('Mars');
// 삭제 확인
console.log(planetsOrderFromSun.has('Mars')); // False
// for of 로 반복돌림
for (const x of planetsOrderFromSun) {
console.log(x); // 넣은 순서대로 나옴 Mercury Venus Earth
}
// 사이즈 확인
console.log(planetsOrderFromSun.size); // 3
// 중복 값 넣어보기
planetsOrderFromSun.add('Venus'); // Trying to add a duplicate
// 사이즈 확인 -> 중복 값 안들어감
console.log(planetsOrderFromSun.size); // Still 3, Did not add the duplicate
// 콜렉션 비우기
planetsOrderFromSun.clear();
console.log(planetsOrderFromSun.size); // 0
Weak Collection, Memory, 가비지 컬렉션
가비지 콜렉션은 메모리 관리의 한 형태이고 객체가 더이상 어딘가에 참조되지 않을 때 자동적으로 삭제한다.
Map, Set 컬렉션의 경우 객체로의 참조가 강하게 일어나는 컬렉션이어서 가비지 컬렉션의 대상이 안된다. 예를 들어 더이상 필요하지 않은 돔 엘리먼트 값을 계속 갖고 있는 경우가 있겠다.
ES6에선 이걸 해결하기 위해 WeakMap과 WeakSet을 사용하는데 객체가 쓸모 없어지면 메모리에서 지워버리게 만든다.
https://codeburst.io/understanding-generators-in-es6-javascript-with-examples-6728834016d5
Understanding Generators in ES6 JavaScript with Examples
ES6 introduced a new way of working with functions and iterators in the form of Generators (or generator functions). A generator is a…
codeburst.io
ES6에서 함수를 반복문과 함께 사용하는 방법을 추가 했는데 이게 Generators( 함수)다. 반복을 하다 중간에 멈출 수 있고 멈춘 시점 부터 다시 반복할 수 있다. ( async/await 가 이 제너레이터 기반이다. )
제너레이터란 무엇인가 ?
일반 함수는 작업을 끝낼 때 까지 멈출 수 없다. 끝내려면 return 해야한다. 아님 에러를 던지던가
제너레이터는 next()를 호출하는 객체를 리턴하는 함수이다. 모든 next() 호출은 { value: anything, done: true | false } 형태의 객체를 리턴한다.
객체 안의 done이 true가 되면 제너레이터는 멈춘다.
위에 사진이 제너레이터가 동작하는 방식이다. 설명은 블로그에 안나와 있어서 나도 못한다.
제너레이터 문법을 보자
function * generator () {}
function* generator () {}
function *generator () {}
let generator = function * () {}
let generator = function* () {}
let generator = function *() {}
let generator = *() => {} // SyntaxError
let generator = ()* => {} // SyntaxError
let generator = (*) => {} // SyntaxError
제너레이터 문법은 function 키워드 바로 뒤에 * 을 붙이면 된다. 화살표 함수와는 사용 못 한다.
제너레이터 함수 안에는 yield라는 키워드가 있는데 이게 return과 비슷한 역할을 한다.
function * withYield(a) {
let b = 5;
yield a + b; // 1번 일드
b = 6; // it will be re-assigned after first execution
yield a * b; // 2번 일드
}
const calcSix = withYield(6);
calcSix.next().value; // 11 -> 1번 일드 리턴됨
calcSix.next().value; // 36 -> 1번 일드 넘기고 2번 일드 리턴됨
yield로 내보낼 값을 정한다. 오직 한번만 리턴한다. 함수를 다시 호출해도 리턴했던 yield 다음 yield가 리턴된다.
불러낼 때 .next().value 로 불러온다. 일반적으로 제너레이터의 아웃풋은 항상 객체이다. 이 객체는 2가지 프로퍼티를 갖고 있는데 하나는 value 값이고 다른 하나는 done이다. 바로 이 done의 값이 true에서 false로 바뀌면 위의 코드처럼 일드를 넘기는거다.
일드처럼 return도 똑같이 객체를 뱉어낸다. 근데 yield가 아니라 return이 값을 뱉어내면 그 제너레이터 함수는 끝난다. 다음 라인에 yield가 있어도 읽지 않는다.