javascript+es6

[ javascript ] 30. Set, Map ,yield, Symbol

변쌤(이젠강남) 2024. 8. 22. 11:34
반응형

Set , Map , yield

 

# Set 

 

Set은 JavaScript의 내장 객체 중 하나로, 중복되지 않은 값을 저장할 수 있는 자료구조입니다. Set 객체는 배열과 비슷하지만, 배열과 달리 동일한 값을 중복해서 가질 수 없습니다. 따라서, Set을 사용하면 중복된 값을 자동으로 제거할 수 있습니다.

Set의 주요 특징

  • 중복 허용하지 않음: Set에 동일한 값을 추가하려고 하면, 자동으로 무시됩니다.
  • 순서가 있음: Set에 추가된 값들은 삽입된 순서대로 저장됩니다.
  • 유일한 값: Set은 원시 값 또는 객체 참조를 유일하게 저장합니다.

 

  설명 mdn
Set Set 객체는 값의 컬렉션입니다. Set의 값은 한 번만 나타날 수 있으며, Set의 컬렉션에서는 고유한 값 mdn
add(value) 같은 값인 요소가 이 Set에 없다면 지정된 값과 함께 새로운 요소를 이 Set에 삽입 mdn
clear()  Set의 모든 요소를 삭제 mdn
delete(value) 지정한 요소를 Set 객체에서 제거 mdn
has(value) Set 객체에 주어진 요소가 존재하는지 여부를 판별해 반환 mdn
size 이 집합의 (고유한) 요소의 수를 반환 mdn
values() 삽입된 순서대로 각 요소의 값을 순회 mdn
keys()  keys() 메서드는 values() 메서드의 별칭 mdn
entries() [값, 값]의 형태로 가진 배열 mdn

 

 

 

- add(value)

  • Set 객체에 주어진 value를 추가합니다.
  • 이미 존재하는 값은 추가되지 않습니다.
  • 반환값: 추가된 Set 객체 자체 (체이닝 가능).
const mySet = new Set();
mySet.add(1);    // Set { 1 }
mySet.add(2);    // Set { 1, 2 }
mySet.add(1);    // Set { 1, 2 } (중복 값은 무시됨)

 

 

 

- delete(value)

  • Set 객체에서 주어진 value를 제거합니다.
  • 반환값: value가 존재해서 삭제된 경우 true, 그렇지 않으면 false.
mySet.delete(2); // true (2가 삭제됨)
mySet.delete(3); // false (3은 Set에 없으므로 삭제되지 않음)

 

 

- has(value)

  • Set 객체에 주어진 value가 존재하는지 확인합니다.
  • 반환값: 값이 존재하면 true, 존재하지 않으면 false.
mySet.has(1); // true
mySet.has(3); // false

 

 

- clear()

  • Set 객체의 모든 값을 제거합니다.
  • 반환값: 없음 (메서드는 undefined를 반환).
mySet.clear();   // Set { } (모든 값이 제거됨)

 

 

- size

  • Set 객체의 크기(저장된 값의 개수)를 반환합니다.
  • 반환값: Set에 저장된 값의 개수 (숫자).
const size = mySet.size; // 2 (현재 Set에 두 개의 값이 있음)

 

 

- forEach(callbackFn[, thisArg])

  • Set 객체의 각 값에 대해 제공된 콜백 함수를 한 번씩 실행합니다.
  • 반환값: 없음 (메서드는 undefined를 반환).
  • callbackFn은 각 값에 대해 호출되는 함수로, 세 가지 인수를 가질 수 있습니다:
    • 현재 값 (value)
    • 동일한 값 (value) - Set의 특성상 첫 번째와 두 번째 인수는 동일함.
    • 현재 순회를 진행 중인 Set 객체 자체 (set).
  • thisArg는 선택적 인수로, 콜백 함수 내에서 this로 사용할 값을 지정할 수 있습니다.

 

mySet.forEach((value) => {
  console.log(value);
});

 

 

- values()

  • Set 객체의 값들을 포함하는 새로운 Iterator 객체를 반환합니다.
  • 반환값: Set 객체의 값들을 순서대로 반환하는 이터레이터 객체.
const iterator = mySet.values();
for (const value of iterator) {
  console.log(value); // 각각의 값을 순서대로 출력
}

 

 

- keys()

  • values()와 동일하게 동작합니다. Set에서는 values()와 keys()가 동일하게 동작하며, 이는 Map 객체와의 일관성을 위해 제공됩니다.
  • 반환값: Set 객체의 값들을 순서대로 반환하는 이터레이터 객체.
const iterator = mySet.keys();
for (const key of iterator) {
  console.log(key); // 각각의 값을 순서대로 출력
}

 

 

- entries()

  • Set 객체의 각 값에 대해 [value, value] 쌍을 포함하는 새로운 Iterator 객체를 반환합니다. 이 쌍은 Map 객체의 entries()와 호환성을 위해 제공됩니다.
  • 반환값: [value, value] 쌍들을 순서대로 반환하는 이터레이터 객체.
const iterator = mySet.entries();
for (const [key, value] of iterator) {
  console.log(key, value); // 각각의 [value, value] 쌍을 출력
}

 

 

- Symbol.iterator

  • Set 객체를 순회할 수 있게 하는 기본 이터레이터 메서드입니다. 이는 for...of 루프에서 사용됩니다.
  • 반환값: Set의 값을 순회할 수 있는 이터레이터 객체.
for (const value of mySet) {
  console.log(value); // Set의 각 값을 순회하면서 출력
}

 

 

 

예시

// Set 객체 생성
const mySet = new Set();

// 값 추가
mySet.add(1);
mySet.add(5);
mySet.add(1); // 중복된 값은 무시됨
mySet.add('Hello');
mySet.add({ name: 'Alice' });

// Set의 크기 확인
console.log(mySet.size); // 4

// Set의 값 확인
console.log(mySet.has(1)); // true
console.log(mySet.has(2)); // false

// Set의 값 삭제
mySet.delete(5);
console.log(mySet.size); // 3

// Set의 모든 값 출력
mySet.forEach(value => {
  console.log(value);
});

// Set의 모든 값을 배열로 변환
const myArray = Array.from(mySet);
console.log(myArray); // [1, 'Hello', { name: 'Alice' }]

// Set의 모든 값 제거
mySet.clear();
console.log(mySet.size); // 0

 

 

 

 

# Map 

 

JavaScript에서 키-값 쌍을 저장할 수 있는 내장 객체입니다. Map은 키와 값의 쌍을 저장하며, 각 키는 고유해야 합니다. 키로는 원시 값이나 객체를 모두 사용할 수 있습니다.

 

  1. set(key, value)
    • Map 객체에 주어진 키(key)와 값(value)을 추가하거나, 기존 키의 값을 업데이트합니다.
    • 반환값: 추가된 Map 객체 자체 (체이닝 가능).
    •  
  2. get(key)
    • Map 객체에서 주어진 키(key)에 해당하는 값을 반환합니다.
    • 반환값: 주어진 키에 해당하는 값, 키가 존재하지 않으면 undefined.
  3. has(key)
    • Map 객체에 주어진 키(key)가 존재하는지 확인합니다.
    • 반환값: 키가 존재하면 true, 존재하지 않으면 false.
  4. delete(key)
    • Map 객체에서 주어진 키(key)에 해당하는 값을 제거합니다.
    • 반환값: 키가 존재해서 삭제된 경우 true, 그렇지 않으면 false.
  5. clear()
    • Map 객체의 모든 키-값 쌍을 제거합니다.
    • 반환값: 없음 (undefined를 반환).
  6. size
    • Map 객체에 저장된 키-값 쌍의 개수를 반환합니다.
    • 반환값: Map에 저장된 키-값 쌍의 개수 (숫자).
  7. forEach(callbackFn[, thisArg])
    • Map 객체의 각 키-값 쌍에 대해 주어진 콜백 함수를 실행합니다.
    • 반환값: 없음 (undefined를 반환).
    • callbackFn은 세 가지 인수를 가질 수 있습니다:
      • 현재 값 (value)
      • 현재 키 (key)
      • 현재 순회를 진행 중인 Map 객체 자체 (map).
    • thisArg는 선택적 인수로, 콜백 함수 내에서 this로 사용할 값을 지정할 수 있습니다.
  8. keys()
    • Map 객체의 키들로 이루어진 새로운 Iterator 객체를 반환합니다.
    • 반환값: Map 객체의 키를 순서대로 반환하는 이터레이터 객체.
  9. values()
    • Map 객체의 값들로 이루어진 새로운 Iterator 객체를 반환합니다.
    • 반환값: Map 객체의 값들을 순서대로 반환하는 이터레이터 객체.
  10. entries()
    • Map 객체의 [key, value] 쌍들로 이루어진 새로운 Iterator 객체를 반환합니다.
    • 반환값: [key, value] 쌍들을 순서대로 반환하는 이터레이터 객체.
  11. Symbol.iterator
    • Map 객체를 순회할 수 있는 기본 이터레이터 메서드입니다. for...of 루프에서 사용됩니다.
    • 반환값: [key, value] 쌍들을 순서대로 반환하는 이터레이터 객체.

 

 

const myMap = new Map();
myMap.set('name', 'Alice');
myMap.set('age', 25);
myMap.set('name', 'Bob'); // 기존 'name' 키의 값이 'Bob'으로 업데이트됨

 

 

console.log(myMap.get('name')); // 'Bob'
console.log(myMap.get('age')); // 25
console.log(myMap.get('gender')); // undefined

 

console.log(myMap.has('name')); // true
console.log(myMap.has('gender')); // false

 

myMap.delete('age'); // true
console.log(myMap.has('age')); // false

 

myMap.clear();   // Map이 비워짐
console.log(myMap.size); // 0

 

const size = myMap.size; // Map에 저장된 항목의 개수 반환

 

myMap.set('name', 'Alice');
myMap.set('age', 25);

myMap.forEach((value, key) => {
  console.log(key + ': ' + value);
});
// 출력:
// name: Alice
// age: 25

 

const keys = myMap.keys();
for (const key of keys) {
  console.log(key); // 'name', 'age'
}

 

const values = myMap.values();
for (const value of values) {
  console.log(value); // 'Alice', 25
}

 

const entries = myMap.entries();
for (const [key, value] of entries) {
  console.log(key + ': ' + value); // 'name: Alice', 'age: 25'
}

 

 

for (const [key, value] of myMap) {
  console.log(key + ': ' + value); // 'name: Alice', 'age: 25'
}

 

 

const myMap = new Map();

// 값 설정
myMap.set('firstName', 'John');
myMap.set('lastName', 'Doe');
myMap.set('age', 30);

// 값 얻기
console.log(myMap.get('firstName')); // 'John'

// 키가 존재하는지 확인
console.log(myMap.has('age')); // true

// 키-값 쌍 삭제
myMap.delete('lastName');
console.log(myMap.has('lastName')); // false

// Map의 크기 확인
console.log(myMap.size); // 2

// Map 순회
myMap.forEach((value, key) => {
  console.log(`${key}: ${value}`);
});
// 출력:
// firstName: John
// age: 30

 

 

# yield

 

yield는 JavaScript에서 제너레이터 함수(generator function)를 정의할 때 사용되는 키워드입니다. 제너레이터 함수는 일반 함수와 달리 실행을 중간에 멈추고, 필요한 시점에 다시 시작할 수 있는 특별한 함수입니다. yield 키워드는 제너레이터 함수 내에서 값을 반환하고, 함수의 실행을 일시 중지합니다.

 

 mdn

  • 일시 중지: yield는 제너레이터 함수의 실행을 일시 중지하고, 특정 값을 호출자에게 반환합니다.
  • 다음 값 요청: yield에서 멈춘 제너레이터 함수는 호출자가 next() 메서드를 호출할 때 다시 실행을 재개합니다.
  • 이터레이터 반환: 제너레이터 함수는 이터레이터(iterator)를 반환하며, 이터레이터의 next() 메서드를 호출함으로써 제너레이터를 순차적으로 실행할 수 있습니다.

 

function* simpleGenerator() {
  console.log('Start');
  yield 1;
  console.log('After first yield');
  yield 2;
  console.log('After second yield');
  yield 3;
  console.log('End');
}

const gen = simpleGenerator();

console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }

 

메서드

  1. next(value)
    • 제너레이터 함수의 실행을 재개합니다. yield 키워드 다음에 도달할 때까지 코드가 실행됩니다.
    • 반환값: { value: any, done: boolean }
      • value: yield에 의해 반환된 값입니다.
      • done: 제너레이터 함수가 종료되었으면 true, 그렇지 않으면 false.
function* countUp() {
  let i = 0;
  while (i < 3) {
    yield i++;
  }
}

const counter = countUp();
console.log(counter.next()); // { value: 0, done: false }
console.log(counter.next()); // { value: 1, done: false }
console.log(counter.next()); // { value: 2, done: false }
console.log(counter.next()); // { value: undefined, done: true }

 

 

2. return(value)

  • 제너레이터 함수의 실행을 종료하고, 주어진 value를 반환합니다.
  • 반환값: { value: any, done: true }
function* generate() {
  yield 1;
  yield 2;
  yield 3;
}

const gen = generate();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.return('Finished')); // { value: 'Finished', done: true }
console.log(gen.next()); // { value: undefined, done: true }

 

 

3. throw(exception)

  • 제너레이터 함수 내에서 예외를 던집니다. yield에서 예외가 발생한 것처럼 작동합니다.
  • 반환값: { value: any, done: boolean } - 예외가 처리되면 반환되는 값과 상태.
function* generate() {
  try {
    yield 1;
  } catch (e) {
    console.log('Caught:', e);
  }
  yield 2;
}

const gen = generate();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.throw(new Error('Something went wrong'))); // 'Caught: Error: Something went wrong'
console.log(gen.next()); // { value: 2, done: false }

 

 

속성

  1. done
    • 이터레이터 객체의 next() 메서드가 반환하는 객체에 포함된 속성입니다.
    • 값: 제너레이터 함수가 완료되었으면 true, 아직 완료되지 않았으면 false.
  2. value
    • 이터레이터 객체의 next() 메서드가 반환하는 객체에 포함된 속성입니다.
    • 값: yield에 의해 반환된 값 또는 제너레이터가 종료되었을 때 undefined.

 

 

function* fibonacci() {
  let [prev, curr] = [0, 1];
  while (true) {
    yield curr;
    [prev, curr] = [curr, prev + curr];
  }
}

const fib = fibonacci();
console.log(fib.next().value); // 1
console.log(fib.next().value); // 1
console.log(fib.next().value); // 2
console.log(fib.next().value); // 3
console.log(fib.next().value); // 5

 

 

fibonacci 제너레이터는 무한히 피보나치 수열을 생성합니다. next() 메서드를 호출할 때마다 다음 숫자가 계산되어 반환됩니다.

yield는 제너레이터 함수에서 값의 시퀀스를 생성하거나, 반복 동작을 제어할 때 매우 유용합니다. 이를 통해 비동기 작업을 제어하거나, 큰 데이터를 필요에 따라 점진적으로 처리하는 등의 다양한 응용이 가능합니다.

 

 

# Symbol 

ECMAScript 6(ES6)에서 도입된 기본 자료형 중 하나로, 고유하고 변경 불가능한 값을 나타냅니다. 주로 객체의 프로퍼티 키로 사용되며, 각 Symbol은 유일한 값을 가지기 때문에 다른 값과 충돌하지 않습니다. 이는 객체의 프로퍼티 키를 정의할 때 주로 사용되어, 이름 충돌을 방지하는 데 유용합니다.

 

Symbol 생성

Symbol은 Symbol() 함수로 생성할 수 있으며, 선택적으로 설명(description)을 전달할 수 있습니다. 이 설명은 디버깅을 위해 주로 사용됩니다.

const symbol1 = Symbol();
const symbol2 = Symbol('description'); // 설명이 있는 Symbol

console.log(symbol1); // 출력: Symbol()
console.log(symbol2); // 출력: Symbol(description)

 

Symbol의 고유성

Symbol로 생성된 값은 서로 고유합니다. 같은 설명을 전달하더라도 각 Symbol은 서로 다릅니다.

 

const symbol1 = Symbol('test');
const symbol2 = Symbol('test');

console.log(symbol1 === symbol2); // 출력: false (고유한 값이므로 다름)

 

 

Symbol을 사용하는 이유

  1. 고유한 프로퍼티 키: Symbol은 유일한 값이므로, 프로퍼티 키가 다른 라이브러리나 코드와 충돌하지 않도록 보호
  2. 은닉성: Symbol로 정의된 프로퍼티는 일반적인 방법으로 접근되지 않으므로, 객체의 프로퍼티를 은닉
  3. 내장 심볼: 내장 심볼을 통해 객체의 기본 동작을 커스터마이즈할 수 있음
반응형