JavaScript type object 중 순회가능 자료형

1 개요[ | ]

JavaScript type object 중 순회가능 자료형

2 iterable[ | ]

  • iterator 있으면 iterable( = for...of 사용 가능)

2.1 iterable 동적 판별[ | ]

class MyClass {}

const testCases = [
  // Not Iterable
  ['null', null],
  ['Date', new Date()],
  ['Error', new Error("msg")],
  ['RegExp', new RegExp("abc")],
  ['WeakMap', new WeakMap()],
  ['WeakSet', new WeakSet()],
  ['MyClass', new MyClass()],
  ['Object', { a: 11, b: 22 }],
  ['console', console],
  ['window', window],

  // Iterable
  ['Array', [11, 22]],
  ['Map', new Map(Object.entries({ a: 11, b: 22 }))],
  ['Set', new Set([11, 22])],
];

testCases.forEach(([name, value]) => {
  const type = typeof value;
  const constructor = value?.constructor?.name ?? '-';
  try {
    for (const _ of value) {}
    console.log(`✔️ [${type}] ${name} (${constructor})`);
  } catch {
    console.log(`❌ [${type}] ${name} (${constructor})`);
  }
});

2.2 iterable 정적 판별[ | ]

class MyClass {}

const testCases = [
  // Not Iterable
  ['null', null],
  ['Date', new Date()],
  ['Error', new Error("msg")],
  ['RegExp', new RegExp("abc")],
  ['WeakMap', new WeakMap()],
  ['WeakSet', new WeakSet()],
  ['MyClass', new MyClass()],
  ['Object', { a: 11, b: 22 }],
  ['console', console],
  ['window', window],

  // Iterable
  ['Array', [11, 22]],
  ['Map', new Map(Object.entries({ a: 11, b: 22 }))],
  ['Set', new Set([11, 22])],
];

testCases.forEach(([name, value]) => {
  const type = typeof value;
  const constructor = value?.constructor?.name ?? '-';  
  const hasIterator = value?.[Symbol.iterator] instanceof Function;
  if (hasIterator) {
    console.log(`✔️ [${type}] ${name} (${constructor})`);
  } else {
    console.log(`❌ [${type}] ${name} (${constructor})`);
  }
});

3 traversable[ | ]

  • 순회가능
  • iterable(for...of 사용가능) + enumerable(for...in 사용가능)

3.1 traversable 동적 판별[ | ]

class MyClass {}

const testCases = [
  // Not Iterable
  ['null', null],
  ['Date', new Date()],
  ['Error', new Error("msg")],
  ['RegExp', new RegExp("abc")],
  ['WeakMap', new WeakMap()],
  ['WeakSet', new WeakSet()],
  ['MyClass', new MyClass()],
  
  // Enumerable (for...in)
  ['Object', { a: 11, b: 22 }],
  ['console', console],
  ['window', window],

  // Iterable (for...of)
  ['Array', [11, 22]],
  ['Map', new Map(Object.entries({ a: 11, b: 22 }))],
  ['Set', new Set([11, 22])],
];

testCases.forEach(([name, value]) => {
  const type = typeof value;
  const constructor = value?.constructor?.name ?? '-';

  // Iterable (for...of)
  const iterable = (() => {
    try {
      for (const _ of value) return true;
    } catch {}
    return false;
  })();

  // Enumerable (for...in)
  const enumerable = (() => {
    try {
      for (const _ in value) return true;
    } catch {}
    return false;
  })();

  console.log(
    `${iterable ? '✔️' : '❌'}${enumerable ? '✔️' : '❌'} [${type}] ${name} (${constructor})`
  );
});

3.2 traversable 정적 판별[ | ]

class MyClass {}

const testCases = [
  // Not Iterable
  ['null', null],
  ['Date', new Date()],
  ['Error', new Error("msg")],
  ['RegExp', new RegExp("abc")],
  ['WeakMap', new WeakMap()],
  ['WeakSet', new WeakSet()],
  ['MyClass', new MyClass()],

  // Enumerable (for...in)
  ['Object', { a: 11, b: 22 }],
  ['console', console],
  ['window', window],

  // Iterable (for...of)
  ['Array', [11, 22]],
  ['Map', new Map(Object.entries({ a: 11, b: 22 }))],
  ['Set', new Set([11, 22])],
];

testCases.forEach(([name, value]) => {
  const type = typeof value;
  const constructor = value?.constructor?.name ?? '-';
  const iterable = value?.[Symbol.iterator] instanceof Function;
  const enumerable = value && typeof value === 'object' && Object.keys(value).length > 0;

  console.log(`${iterable ? '✔️' : '❌'}${enumerable ? '✔️' : '❌'} [${type}] ${name} (${constructor})`);
});

4 통합 traverse[ | ]

const testCases = [
  ['Array', [11, 22]],
  ['Set', new Set([11, 22])],
  ['Object', { foo: 11, bar: 22 }],
  ['Map', new Map(Object.entries({ foo: 11, bar: 22 }))],
  ['console', console],
  ['window', window],
];

function getEntries(obj) {
  if (Array.isArray(obj)) {
    return obj.map((value, index) => [index, value]);
  }
  if (obj instanceof Map) {
    return [...obj.entries()];
  }
  if (obj instanceof Set) {
    return [...obj].map((value, index) => [index, value]);
  }
  if (obj && typeof obj === 'object') {
    return Object.entries(obj);
  }
  return [];
}

testCases.forEach(([name, obj]) => {
  console.log(name);
  const entries = getEntries(obj);
  entries.some(([key, value], index) => {
    if (index >= 3) {
      console.log(`  ...`);
      return true;
    }
    console.log(`  [${index}] ${key}: ${value}`);
  });
});

5 같이 보기[ | ]

문서 댓글 ({{ doc_comments.length }})
{{ comment.name }} {{ comment.created | snstime }}