Skip to content

Arrays (๋ฐฐ์—ด) โ€‹

๋ฐฐ์—ด์€ ๋ฐ์ดํ„ฐ์˜ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ์ €์žฅํ•˜๋Š” ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ๊ตฌ์กฐ๋‹ค.
Airbnb ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ์—์„œ๋Š” ๋ช…ํ™•ํ•œ ์ƒ์„ฑ ๋ฐฉ์‹๊ณผ ๋ถˆํ•„์š”ํ•œ ์ค‘๊ฐ„ ๋ฐฐ์—ด ๋ฐฉ์ง€, ๊ทธ๋ฆฌ๊ณ  ์ผ๊ด€๋œ ์ˆœํšŒ ํŒจํ„ด์„ ๊ถŒ์žฅํ•œ๋‹ค.

๐Ÿงฉ Note

๋ฐฐ์—ด์€ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆœ์„œ๋Œ€๋กœ ๋‹ค๋ฃจ๋Š” ๊ฐ€์žฅ ๋‹จ์ˆœํ•˜์ง€๋งŒ ๊ฐ•๋ ฅํ•œ ๊ตฌ์กฐ๋‹ค.
Airbnb ๊ฐ€์ด๋“œ๋Š” ๋ฐฐ์—ด์˜ ์ƒ์„ฑยท๋ณต์‚ฌยท๋ณ€ํ™˜ ๋ฐฉ์‹์„ ๋ช…ํ™•ํžˆ ์ •์˜ํ•ด, ์ฝ”๋“œ์˜ ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ๊ณผ ๋ถˆ๋ณ€์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ๋ชฉ์ ์ด ์žˆ๋‹ค.

1. ๋ฐฐ์—ด์„ ์ƒ์„ฑํ•  ๋•Œ๋Š” ๋ฆฌํ„ฐ๋Ÿด ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉ โ€‹

eslint: no-array-constructor

js
// bad
const items = new Array();

// good
const items = [];

๐Ÿ’ก new Array()๋Š” ์ธ์ž์˜ ๊ฐœ์ˆ˜์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•ด ํ˜ผ๋™์„ ์œ ๋ฐœํ•œ๋‹ค.

๋ฐ˜๋ฉด []๋Š” ํ•ญ์ƒ ๋ช…ํ™•ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์žฅํ•œ๋‹ค.

js
new Array(3); // [ <3 empty items> ]
new Array(1, 2, 3); // [1, 2, 3]

2. ๋ฐฐ์—ด์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•  ๋•Œ๋Š” ์ง์ ‘ ์ธ๋ฑ์Šค ํ• ๋‹น ๋Œ€์‹  push() ์‚ฌ์šฉ โ€‹

js
const someStack = [];

// bad
someStack[someStack.length] = 'abracadabra';

// good
someStack.push('abracadabra');
  • push๋Š” ์˜๋„๋ฅผ ๋ช…ํ™•ํžˆ ํ‘œํ˜„ํ•˜๊ณ , ํ˜‘์—… ์‹œ ์˜๋ฏธ๋ฅผ ๋น ๋ฅด๊ฒŒ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ๋‹ค.

3. ๋ฐฐ์—ด์„ ๋ณต์‚ฌํ•  ๋•Œ๋Š” ์ „๊ฐœ ์—ฐ์‚ฐ์ž ...๋ฅผ ์‚ฌ์šฉ โ€‹

js
// ์›๋ณธ ๋ฐฐ์—ด
const items = ['apple', 'banana', 'cherry'];

// bad
const len = items.length; // ์›๋ณธ ๋ฐฐ์—ด์˜ ๊ธธ์ด ์ €์žฅ
const itemsCopy = []; // ๋ณต์‚ฌ๋ณธ์„ ๋‹ด์„ ๋นˆ ๋ฐฐ์—ด
let i;

for (i = 0; i < len; i += 1) {
  itemsCopy[i] = items[i]; // ์›๋ณธ์˜ ๊ฐ ์š”์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ์ƒˆ ๋ฐฐ์—ด์— ๋ณต์‚ฌ
}

console.log(itemsCopy); // ['apple', 'banana', 'cherry']

// good
// ์ „๊ฐœ ์—ฐ์‚ฐ์ž๋Š” ์œ„ ๊ณผ์ •์„ ํ•œ ์ค„๋กœ ๋‹จ์ถ•์‹œํ‚ด
const itemsCopy = [...items];

console.log(itemsCopy); // ['apple', 'banana', 'cherry']
  • bad:
    ์ง์ ‘ ์ธ๋ฑ์Šค๋ฅผ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๊ณ , ์˜๋„(๋ณต์‚ฌ)๊ฐ€ ์ฝ”๋“œ๋งŒ ๋ณด๊ณ  ๋ฐ”๋กœ ๋“œ๋Ÿฌ๋‚˜์ง€ ์•Š๋Š”๋‹ค. (์œ ์ง€๋ณด์ˆ˜์„ฑ โ†“, ๊ฐ€๋…์„ฑ โ†“)
  • good:
    ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” for๋ฌธ์ฒ˜๋Ÿผ ์ˆœํšŒํ•˜์ง€๋งŒ, ์ฝ”๋“œ๋Š” ๋‹จ ํ•œ ์ค„์ด๊ณ , ์˜๋„๊ฐ€ ๋ฐฐ์—ด ๋ณต์‚ฌ๋ผ๋Š” ๊ฒŒ ๋ฐ”๋กœ ์ฝํžŒ๋‹ค.

4. ์ˆœํšŒ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๋ฅผ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ๋Š” Array.from ๋Œ€์‹  ...์œผ๋กœ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ โ€‹

js
// NodeList ์ƒ์„ฑ
const foo = document.querySelectorAll('.foo');

// good
const nodes = Array.from(foo);

// best
const nodes = [...foo];
  • DOM NodeList, Set, Map ๊ฐ™์€ ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋Š” ์ „๊ฐœ๋กœ ์‰ฝ๊ฒŒ ๋ฐฐ์—ดํ™” ๊ฐ€๋Šฅํ•˜๋‹ค.
  • Array.from()๋ณด๋‹ค [...foo]๊ฐ€ ์ง๊ด€์ ์ด๋ฉฐ, ๊ฐ€๋…์„ฑ์ด ๋†’๋‹ค.
  • [...foo]๋Š” ๋‹จ์ˆœํžˆ ํŽผ์ณ ๋‹ด๋Š”๋‹ค๊ฐ€ ์•„๋‹ˆ๋ผ, ๋‚ด๋ถ€์ ์œผ๋กœ ์ดํ„ฐ๋ ˆ์ดํ„ฐ ํ”„๋กœํ† ์ฝœ(Symbol.iterator)์„ ํ˜ธ์ถœํ•ด ๋ชจ๋“  ์š”์†Œ๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ƒˆ ๋ฐฐ์—ด์„ ๊ตฌ์„ฑํ•˜๋Š” ๋ฌธ๋ฒ•์  ๋‹จ์ถ•ํ˜•์ด๋‹ค.

๐Ÿงฉ iterable ๊ฐ์ฒด

์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋Š” ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด, ์ฆ‰ for-of๋ฌธ์ด๋‚˜ ์ „๊ฐœ ์—ฐ์‚ฐ์ž...๋กœ ์ˆœํšŒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋‹ค.
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ๋Š” ์•„๋ž˜ ์ž๋ฃŒํ˜•๋“ค์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋‹ค.

๊ตฌ๋ถ„์˜ˆ์‹œ์„ค๋ช…
Array[1, 2, 3]์ˆœํšŒ ๊ฐ€๋Šฅ
String"hello"๋ฌธ์ž ๋‹จ์œ„๋กœ ์ˆœํšŒ ๊ฐ€๋Šฅ
Mapnew Map()ํ‚ค-๊ฐ’ ์Œ ์ˆœํšŒ ๊ฐ€๋Šฅ
Setnew Set()์ค‘๋ณต ์—†๋Š” ๊ฐ’ ์ˆœํšŒ ๊ฐ€๋Šฅ
NodeListdocument.querySelectorAll('.foo')DOM ๋…ธ๋“œ ์ง‘ํ•ฉ
TypedArraynew Uint8Array([1,2,3])๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ˆœํšŒ ๊ฐ€๋Šฅ

์ฆ‰, ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋Š” ๋ฐ˜๋ณต ๊ทœ์น™์„ ์ •์˜ํ•œ ํŠน๋ณ„ํ•œ ๋ฉ”์„œ๋“œ Symbol.iterator๋ฅผ ๋‚ด๋ถ€์— ๊ฐ€์ง€๊ณ  ์žˆ์–ด์„œ, ์ „๊ฐœ๋‚˜ for-of๋ฅผ ํ†ตํ•ด ํ•˜๋‚˜์”ฉ ๊บผ๋‚ผ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋‹ค.


1. NodeList๋Š” ๋ฐฐ์—ด์ด ์•„๋‹ˆ๋‹ค.

์ด ์ฝ”๋“œ์—์„œ document.querySelectorAll('.foo')๋Š” NodeList๋ผ๋Š” ํƒ€์ž…์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

html
<div class="foo">A</div>
<div class="foo">B</div>
<div class="foo">C</div>
js
const foo = document.querySelectorAll('.foo');

console.log(foo); // NodeList(3) [div.foo, div.foo, div.foo]
console.log(foo[0]); // <div class="foo">A</div>
console.log(foo.length); // 3
  • NodeList๋Š” ๋ฐฐ์—ด์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ๋ฐฐ์—ด์ด ์•„๋‹ˆ๋‹ค.

  • ์ฆ‰, map(), filter() ๊ฐ™์€ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์ง์ ‘ ์“ธ ์ˆ˜ ์—†๋‹ค. ์ง„์งœ ๋ฐฐ์—ด์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฐฐ์—ด์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์†๋ฐ›์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

    js
    foo.map((el) => el.textContent); // TypeError: foo.map is not a function
  • ํ•˜์ง€๋งŒ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ผ์„œ, ๋ฐ˜๋ณต์€ ๊ฐ€๋Šฅํ•˜๋‹ค.

    js
    // NodeList๊ฐ€ ์ดํ„ฐ๋Ÿฌ๋ธ”์ธ ์ด์œ ๋Š”, NodeList ๋‚ด๋ถ€์—๋Š” ํŠน๋ณ„ํ•œ ์†์„ฑ์ด ์žˆ๋‹ค.
    // Symbol.iterator๊ฐ€ ์กด์žฌํ•œ๋‹ค๋Š” ๋œป์€, ์ˆœํšŒ ๊ทœ์น™์ด ์žˆ์–ด์„œ for-of๋กœ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์˜๋ฏธ
    console.log(typeof foo[Symbol.iterator]); // "function"
    js
    // ๊ทธ๋ž˜์„œ ์•„๋ž˜ ์ฝ”๋“œ๊ฐ€ ๋™์ž‘ํ•œ๋‹ค.
    for (const el of foo) {
      console.log(el); // ๊ฐ DOM ์š”์†Œ ์ถœ๋ ฅ๋จ
    }
    
    // ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ด๋Ÿฐ ํ๋ฆ„์ด๋‹ค.
    const iterator = foo[Symbol.iterator]();
    console.log(iterator.next()); // { value: <div.foo>, done: false }
    console.log(iterator.next()); // { value: <div.foo>, done: false }
    console.log(iterator.next()); // { value: <div.foo>, done: false }
    console.log(iterator.next()); // { value: undefined, done: true }

2. ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•: Array-from()

Array-from()์€ ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋ฅผ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ํ‘œ์ค€ ๋ฉ”์„œ๋“œ์ด๋‹ค.

js
const nodes = Array.from(foo);
  • ์ด์ œ nodes๋Š” ์™„์ „ํ•œ ๋ฐฐ์—ด์ด ๋˜์–ด์„œ map(), filter() ๋“ฑ์„ ๋ฐ”๋กœ ์“ธ ์ˆ˜ ์žˆ๋‹ค.
js
nodes.map((el) => el.textContent);

3. ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•: ์ „๊ฐœ ์—ฐ์‚ฐ์ž...

js
const nodes = [...foo];
  • ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
js
const nodes = [];
for (const el of foo) {
  nodes.push(el);
}
  • ์ฆ‰, ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋ฅผ ํ•œ ๋ฒˆ ํ’€์–ด์„œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด๋กœ ๋งŒ๋“œ๋Š” ๋ฌธ๋ฒ•์ด๋‹ค.

๐Ÿ’ก ๋‹จ์ˆœ ๋ณ€ํ™˜์ด๋ผ๋ฉด ์ „๊ฐœ ์—ฐ์‚ฐ์ž๋ฅผ ์“ฐ๊ณ , Array.from()์€ map ์ฝœ๋ฐฑ์ด ํ•„์š”ํ•  ๋•Œ๋งŒ ์“ฐ๋ผ๋Š” ๋œป..! ๋ผ๊ณ  ๋งํ•˜๋Š” ๊ฑฐ์˜ˆ์š”.

๐Ÿงฉ ์ „๊ฐœ ์—ฐ์‚ฐ์ž๊ฐ€ ๋‚ด๋ถ€์—์„œ ์‹ค์ œ๋กœ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

html
<div class="foo">A</div>
<div class="foo">B</div>
<div class="foo">C</div>
js
const foo = document.querySelectorAll('.foo');
const nodes = [...foo];

1. foo๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด (NodeList)

js
foo = NodeList(3)[(div.foo, div.foo, div.foo)];

// ์œ„ NodeList๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์ด๋Ÿฐ ์ดํ„ฐ๋Ÿฌ๋ธ” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค.
foo[Symbol.iterator] = function () {
  // ์ˆœํšŒ ๊ทœ์น™ ์ •์˜
};
  • ์ฆ‰, foo๋Š” for-of๋ฌธ์ด๋‚˜ ์ „๊ฐœ ๊ตฌ๋ฌธ์œผ๋กœ ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ์ž„์„ ์„ ์–ธํ•˜๊ณ  ์žˆ๋‹ค.

2. ์ „๊ฐœ ๊ตฌ๋ฌธ (...foo)์ด ์‹คํ–‰๋  ๋•Œ ๋‚ด๋ถ€ ๋™์ž‘

์—”์ง„์€ ์‹ค์ œ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ผ์„ ์ž๋™์œผ๋กœ ํ•œ๋‹ค.

js
const iterator = foo[Symbol.iterator](); // โ‘  ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด ๊บผ๋‚ด๊ธฐ
const resultArray = []; // โ‘ก ๊ฒฐ๊ณผ๋ฅผ ๋‹ด์„ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด ์ค€๋น„

let next = iterator.next(); // โ‘ข ์ฒซ ๋ฒˆ์งธ ๊ฐ’ ๊บผ๋‚ด๊ธฐ
while (!next.done) {
  // โ‘ฃ ๋๊นŒ์ง€ ๋ฐ˜๋ณต
  resultArray.push(next.value); // โ‘ค ๊บผ๋‚ธ ๊ฐ’ ์ €์žฅ
  next = iterator.next(); // โ‘ฅ ๋‹ค์Œ ๊ฐ’ ์š”์ฒญ
}

js
const nodes = [...foo];
// ์ฆ‰, ์œ„ ์ฝ”๋“œ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์•„๋ž˜ ์ฝ”๋“œ์™€ ๋™์ผํ•˜๋‹ค.

const nodes = [];
for (const element of foo) {
  nodes.push(element);
}

3. ๋™์ž‘ ํ๋ฆ„

๋‹จ๊ณ„๋™์ž‘์„ค๋ช…
โ‘ foo[Symbol.iterator]() ํ˜ธ์ถœ๋ฐ˜๋ณต์ž(iterator) ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜ด
โ‘กiterator.next() ์‹คํ–‰์ฒซ ๋ฒˆ์งธ DOM ์š”์†Œ ๋ฐ˜ํ™˜
โ‘ขvalue๋ฅผ ์ƒˆ ๋ฐฐ์—ด์— push๋ณต์‚ฌ ์ €์žฅ
โ‘ฃdone์ด true์ผ ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต๋ชจ๋“  ์š”์†Œ๋ฅผ ์ˆœํšŒ
โ‘ค์™„์„ฑ๋œ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜์ƒˆ ๋ฐฐ์—ด(nodes)์ด ๋งŒ๋“ค์–ด์ง

4. ์ฆ‰, [...foo]๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ for-of + push()๋ฅผ ์ž๋™์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ์งง์€ ๋ฌธ๋ฒ•์ด๋‹ค.

js
// ์ „ํ†ต์ ์ธ ๋ฐฉ์‹
const nodes = [];
for (const el of foo) {
  nodes.push(el);
}

// ์ตœ์‹  ๋ฐฉ์‹
const nodes = [...foo];

๊ตฌ๋ถ„์„ค๋ช…
์ดํ„ฐ๋Ÿฌ๋ธ”Symbol.iterator ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด
์ „๊ฐœ ์—ฐ์‚ฐ์ž(...)์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ์š”์†Œ๋ฅผ ํ•˜๋‚˜์”ฉ ๊บผ๋‚ด์„œ ํŽผ์นจ
๋‚ด๋ถ€ ๋™์ž‘for...of ๋ฌธ์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋ฉฐ push๋กœ ์ƒˆ ๋ฐฐ์—ด ์ƒ์„ฑ
๊ฒฐ๊ณผ์–•์€ ๋ณต์‚ฌ๋œ ์ƒˆ ๋ฐฐ์—ด์ด ๋งŒ๋“ค์–ด์ง

5. ์œ ์‚ฌ ๋ฐฐ์—ด(Array-like) ๊ฐ์ฒด๋ฅผ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•  ๋•Œ๋Š” Array.from์„ ์‚ฌ์šฉ โ€‹

js
const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };

// bad
const arr = Array.prototype.slice.call(arrLike);

// good
const arr = Array.from(arrLike);
  • ์œ ์‚ฌ ๋ฐฐ์—ด์€ length ์†์„ฑ์€ ์žˆ์ง€๋งŒ iterable์ด ์•„๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ „๊ฐœ ...๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š๊ณ , Array.from()์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿงฉ ์œ ์‚ฌ ๋ฐฐ์—ด ๊ฐ์ฒด(Array-like Object)

์œ ์‚ฌ ๋ฐฐ์—ด์ด๋ž€ ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ƒ๊ฒผ์ง€๋งŒ ์‹ค์ œ ๋ฐฐ์—ด์ด ์•„๋‹Œ ๊ฐ์ฒด์ด๋‹ค.
์ฆ‰, index์™€ length ์†์„ฑ์€ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ, ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ(map, filter, push ๋“ฑ)๋Š” ์ „ํ˜€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

js
const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };

console.log(arrLike[0]); // 'foo'
console.log(arrLike.length); // 3
console.log(Array.isArray(arrLike)); // false

์ด ๊ฐ์ฒด๋Š” ๋ณด๊ธฐ์— ๋ฐฐ์—ด ๊ฐ™์ง€๋งŒ ์ธ๋ฑ์Šค๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , length๋„ ์žˆ๋‹ค. ์‹ค์ œ ๋ฐฐ์—ด์ด ์•„๋‹ˆ๋ผ ๋‹จ์ˆœํ•œ ๊ฐ์ฒด๋‹ค.


1. ์™œ ์ด๋Ÿฐ ๊ฐ์ฒด๊ฐ€ ์ƒ๊ธธ๊นŒ?

์˜ˆ์‹œ์„ค๋ช…
argumentsํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์ „๋‹ฌ๋œ ์ธ์ž๋ฅผ ๋‹ด๋Š” ๋‚ด์žฅ ๊ฐ์ฒด
NodeListDOM API (document.querySelectorAll) ๋ฐ˜ํ™˜๊ฐ’
HTMLCollectiongetElementsByClassName, children ๊ฒฐ๊ณผ
{0: 'a', 1: 'b', length: 2}์ธ๋ฑ์Šค์™€ length๋ฅผ ์ง์ ‘ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด

์œ ์‚ฌ ๋ฐฐ์—ด์€ ์ข…์ข… ๋“ฑ์žฅํ•œ๋‹ค. ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ƒ๊ฒผ์ง€๋งŒ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋ฅผ ์“ธ ์ˆ˜ ์—†๋‹ค.

js
function showArgs() {
  console.log(arguments.map); // undefined
}
showArgs('a', 'b', 'c');

2. ๋ฐฐ์—ด์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์ง„์งœ ๋ฐฐ์—ด์ด ์•„๋‹˜

์ฆ‰, ์ด๋Ÿฐ ๊ฐ์ฒด๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”๋„ ์•„๋‹ˆ๊ณ , ๋‹จ์ง€ 0๋ถ€ํ„ฐ length-1๊นŒ์ง€์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ง„ ๊ฐ์ฒด์ผ ๋ฟ์ด๋‹ค.
๊ทธ๋ž˜์„œ ์ „๊ฐœ ์—ฐ์‚ฐ์ž๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

js
const arrLike = { 0: 'foo', 1: 'bar', length: 2 };
const arr = [...arrLike]; // TypeError: arrLike is not iterable

3. ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•: ๊ณผ๊ฑฐ ๋ฐฉ์‹

js
// ๊ณผ๊ฑฐ์—” ์ด๋Ÿฐ ์‹์œผ๋กœ ์–ต์ง€๋กœ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ–ˆ๋‹ค.
const arr = Array.prototype.slice.call(arrLike);

// ์œ„๋Š” ์‚ฌ์‹ค์ƒ ์ด๋ ‡๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.
const arr = Array.prototype.slice.apply(arrLike);
  • slice()๋Š” ์›๋ž˜ ๋ฐฐ์—ด์šฉ ๋ฉ”์„œ๋“œ์ธ๋ฐ, call()๋กœ ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ƒ๊ธด ๊ฐ์ฒด์— ์ž„์‹œ๋กœ ๋ถ™์—ฌ์„œ ์‹คํ–‰ํ•œ ๊ฒƒ์ด๋‹ค.
  • ๋™์ž‘์€ ๋˜์ง€๋งŒ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š” ๋ฐฉ์‹์ด๋‹ค.

4. ๋ณ€ํ™˜ ๋ฐฉ๋ฒ•: ๊ถŒ์žฅ ๋ฐฉ์‹ Array.from()

ES6 ์ดํ›„๋ถ€ํ„ฐ ๊ถŒ์žฅ๋˜๋Š” ๋ฐฉ์‹์ด๋‹ค.

js
// ์ง„์งœ ๋ฐฐ์—ด์ด ๋œ๋‹ค.
const arr = Array.from(arrLike);

console.log(arr); // ['foo', 'bar', 'baz']
console.log(Array.isArray(arr)); // true
  • map(), filter(), reduce() ๋“ฑ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ๋„ ์ •์ƒ ์ž‘๋™ํ•œ๋‹ค.

Array.from()์€ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋งคํ•‘ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.

js
const arr = Array.from(arrLike, (item) => item.toUpperCase());
console.log(arr); // ['FOO', 'BAR', 'BAZ']
  • ์ฆ‰, ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜ํ•˜๋ฉด์„œ ๋™์‹œ์— ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€๊ณตํ•  ์ˆ˜ ์žˆ๋‹ค.

5. ์ „๊ฐœ๊ฐ€ ์•ˆ๋˜๋Š” ์ด์œ 

... ์—ฐ์‚ฐ์ž๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด๋งŒ ํŽผ์น  ์ˆ˜ ์žˆ๋‹ค.

js
const arrLike = { 0: 'a', 1: 'b', length: 2 };
const arr = [...arrLike]; // TypeError

// ๋‚ด๋ถ€์ ์œผ๋กœ ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ!
arrLike[Symbol.iterator]; // undefined
  • ์ฆ‰, arrLike๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ” ํ”„๋กœํ† ์ฝœ์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ „๊ฐœ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ตฌ๋ถ„์„ค๋ช…
์œ ์‚ฌ ๋ฐฐ์—ด์ธ๋ฑ์Šค์™€ length๋งŒ ๊ฐ€์ง„ ๊ฐ์ฒด (๋ฐฐ์—ด ์•„๋‹˜)
์˜ˆ์‹œarguments, HTMLCollection, {0:'a', length:1}
๋ฌธ์ œ์ ๋ฐฐ์—ด ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€, ์ „๊ฐœ(...) ๋ถˆ๊ฐ€๋Šฅ
ํ•ด๊ฒฐ๋ฒ• (๊ณผ๊ฑฐ)Array.prototype.slice.call(obj)
ํ•ด๊ฒฐ๋ฒ• (ํ˜„๋Œ€)Array.from(obj)
Array.from(obj, mapFn)์œผ๋กœ ๋ณ€ํ™˜+๋งคํ•‘ ๊ฐ€๋Šฅ

์œ ์‚ฌ ๋ฐฐ์—ด์€ ๋ฐฐ์—ด์ฒ˜๋Ÿผ ์ƒ๊ธด ๊ฐ์ฒด์ง€๋งŒ ์ดํ„ฐ๋Ÿฌ๋ธ”์ด ์•„๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ...๋กœ ํŽผ์น  ์ˆ˜ ์—†๊ณ , Array.from()์„ ์‚ฌ์šฉํ•ด์•ผ ์ง„์งœ ๋ฐฐ์—ด๋กœ ๋ณ€ํ™˜๋œ๋‹ค.


6. ๋งคํ•‘ํ•  ๋•Œ๋Š” ์ „๊ฐœ ... ๋Œ€์‹  Array.from()์„ ์‚ฌ์šฉ โ€‹

์ค‘๊ฐ„ ๋ฐฐ์—ด ์ƒ์„ฑ์„ ๋ฐฉ์ง€ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

js
// bad
const baz = [...foo].map(bar);

// good
const baz = Array.from(foo, bar);
  • Array.from()์€ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋งคํ•‘ ์ฝœ๋ฐฑ์„ ๋ฐ›๋Š”๋‹ค.
  • ๋”ฐ๋ผ์„œ ์ค‘๊ฐ„ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์ง€ ์•Š์•„ ์„ฑ๋Šฅ์ƒ ์ด์ ์ด ์žˆ๋‹ค.

๐Ÿงฉ ์ค‘๊ฐ„ ๋ฐฐ์—ด์ด๋ž€?

... ์ „๊ฐœ๋ฅผ ๋‚จ์šฉํ•ด์„œ ๋ถˆํ•„์š”ํ•œ ์ค‘๊ฐ„ ๋ฐฐ์—ด์„ ์ž์ฃผ ๋งŒ๋“ค์–ด๋‚ธ๋‹ค.


1. ์ค‘๊ฐ„ ๋ฐฐ์—ด์ด๋ž€

js
const baz = [...foo].map(bar);

์œ„ ์ฝ”๋“œ๋Š” ๋ฌธ์ œ ์—†์–ด ๋ณด์ด์ง€๋งŒ, ๋‚ด๋ถ€์ ์œผ๋กœ ๋‘ ๋‹จ๊ณ„์˜ ๋ฉ”๋ชจ๋ฆฌ ์ž‘์—…์ด ์ผ์–ด๋‚œ๋‹ค.

js
// ๋‚ด๋ถ€์ ์œผ๋กœ ์ด๋Ÿฐ ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ์…ˆ์ด๋‹ค
const temp = [...foo]; // ์ž„์‹œ ๋ฐฐ์—ด
const baz = temp.map(bar); // ์ƒˆ๋กœ์šด ๋ฐฐ์—ด
    1. [...foo]
      foo (์ดํ„ฐ๋Ÿฌ๋ธ” ๊ฐ์ฒด ๋“ฑ)๋ฅผ ์ƒˆ ๋ฐฐ์—ด๋กœ ๋ณต์‚ฌ โ†’ ์ž„์‹œ ๋ฐฐ์—ด์ด ํ•œ ๋ฒˆ ๋งŒ๋“ค์–ด์ง„๋‹ค.
    1. .map(bar)
      ๊ทธ ์ƒˆ ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ bar ํ•จ์ˆ˜๋ฅผ ์ ์šฉ โ†’ ๊ฒฐ๊ณผ ๋ฐฐ์—ด์ด ๋˜ ๋งŒ๋“ค์–ด์ง„๋‹ค.

์ฆ‰, ์ด 2๊ฐœ์˜ ๋ฐฐ์—ด์ด ์ƒ๊ธด๋‹ค:

  • foo๋ฅผ ์ „๊ฐœํ•ด ๋งŒ๋“  ์ž„์‹œ ๋ฐฐ์—ด
  • map() ๊ฒฐ๊ณผ๋กœ ๋‚˜์˜จ ์ƒˆ ๋ฐฐ์—ด

2. ํ•ด๊ฒฐ๋ฒ•: Array.from(iterable, mapFn)
Array.from()์€ ๋‘ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋งคํ•‘ ์ฝœ๋ฐฑ ํ•จ์ˆ˜(mapFn)๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค.
์ฆ‰, ๋ณ€ํ™˜๊ณผ ๋งคํ•‘์„ ํ•œ ๋ฒˆ์— ํ•  ์ˆ˜ ์žˆ๋‹ค.

js
const baz = Array.from(foo, bar);

// ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” ์ด๋Ÿฐ ์˜๋ฏธ๋‹ค.
const baz = [];
for (const el of foo) {
  baz.push(bar(el));
}
  • ์ฆ‰, foo์˜ ๊ฐ ์š”์†Œ๋ฅผ ๋ฐ”๋กœ ๋ณ€ํ™˜ํ•ด์„œ ์ƒˆ ๋ฐฐ์—ด์— ๋„ฃ๋Š”๋‹ค. ์ค‘๊ฐ„ ๋ฐฐ์—ด์ด ์ƒ๊ธฐ์ง€ ์•Š๋Š”๋‹ค.

๋‘ ๋ฐฉ์‹์„ ๋น„๊ตํ•ด๋ณด๋ฉด,

๊ตฌ๋ถ„์ฝ”๋“œ๋ฐฐ์—ด ์ƒ์„ฑ ํšŸ์ˆ˜๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์†๋„
bad[...foo].map(bar)2๋ฒˆ (์ž„์‹œ + ๊ฒฐ๊ณผ)๋‚ญ๋น„ ๋ฐœ์ƒ๋А๋ฆผ
goodArray.from(foo, bar)1๋ฒˆ (๊ฒฐ๊ณผ๋งŒ)ํšจ์œจ์ ๋น ๋ฆ„
js
// ์˜ˆ์‹œ
const foo = new Set([1, 2, 3]);

// bad
const baz1 = [...foo].map((x) => x * 2);
// ๋‚ด๋ถ€ ๋™์ž‘: [1, 2, 3] โ†’ [2, 4, 6]

// good
const baz2 = Array.from(foo, (x) => x * 2);
// ๋‚ด๋ถ€ ๋™์ž‘: ๋ฐ”๋กœ [2, 4, 6]
  • ๊ฒฐ๊ณผ๋Š” ๊ฐ™์ง€๋งŒ, bad ๋ฐฉ์‹์€ ๋ถˆํ•„์š”ํ•œ ์ž„์‹œ ๋ฐฐ์—ด [1, 2, 3]์„ ๋งŒ๋“ ๋‹ค.

  • bad ๋‚ด๋ถ€ ๋™์ž‘ ์š”์•ฝ

    1. foo(Set)๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์ด๋ฏ€๋กœ ์ „๊ฐœ ๊ฐ€๋Šฅ
    2. ์—”์ง„์€ foo๋ฅผ ์ˆœํšŒํ•˜๋ฉฐ ์ƒˆ ๋ฐฐ์—ด์„ ์ƒ์„ฑ
    3. .map()์ด ๊ทธ ์ƒˆ ๋ฐฐ์—ด์„ ์ˆœํšŒํ•ด ๋˜ ๋‹ค๋ฅธ ๋ฐฐ์—ด(baz)์„ ์ƒ์„ฑํ•œ๋‹ค.

    ๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ์— ๋‘ ๊ฐœ์˜ ๋ฐฐ์—ด ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๊ฒŒ ๋œ๋‹ค.

  • good ๋‚ด๋ถ€ ๋™์ž‘ ์š”์•ฝ

    1. Array.from์ด foo์˜ ์ดํ„ฐ๋ ˆ์ดํ„ฐ(Symbol.iterator)๋ฅผ ์‚ฌ์šฉ
    2. ์ˆœํšŒํ•˜๋ฉด์„œ ๊ฐ ์š”์†Œ๋ฅผ mapFn(x => x * 2)๋กœ ๋ฐ”๋กœ ๋ณ€ํ™˜
    3. ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ํ•˜๋‚˜์˜ ์ƒˆ ๋ฐฐ์—ด(baz)์— ์ง์ ‘ ๋‹ด์Œ

    ์ค‘๊ฐ„ ๋ฐฐ์—ด์ด ์—†๋‹ค!


3. Array.from()์˜ ๋‘ ๋ฒˆ์งธ ์ธ์ž(mapFn)
์ด ์ธ์ž๋Š” Array.prototype.map()๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

js
Array.from(arrayLike, (value, index) => {
  // value: ๊ฐ ์š”์†Œ
  // index: ์ธ๋ฑ์Šค
  // thisArg: ์„ ํƒ์  ์„ธ ๋ฒˆ์งธ ์ธ์ž๋กœ ๋ฐ”์ธ๋”ฉํ•  ๊ฐ’
});
js
// ์˜ˆ์‹œ
const doubled = Array.from({ length: 5 }, (_, i) => i * 2);
console.log(doubled); // [0, 2, 4, 6, 8]
  • ์ด๋Ÿฐ ์‹์œผ๋กœ ๋ฐฐ์—ด ์ƒ์„ฑ + ๋งคํ•‘์„ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ตฌ๋ถ„์„ค๋ช…
[...]์ดํ„ฐ๋Ÿฌ๋ธ”์„ ๋จผ์ € ๋ฐฐ์—ด๋กœ ๋ณต์‚ฌ (์ž„์‹œ ๋ฐฐ์—ด ์ƒ์„ฑ๋จ)
.map()๋ณต์‚ฌ๋œ ๋ฐฐ์—ด์„ ๋‹ค์‹œ ๋งคํ•‘ํ•˜์—ฌ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด ์ƒ์„ฑ
Array.from(iterable, mapFn)๋ณ€ํ™˜๊ณผ ๋งคํ•‘์„ ํ•œ ๋ฒˆ์— ์ˆ˜ํ–‰
์žฅ์ ๋ถˆํ•„์š”ํ•œ ๋ฐฐ์—ด ์ƒ์„ฑ ๋ฐฉ์ง€ โ†’ ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ โ†‘, ์†๋„ โ†‘

์ „๊ฐœ + map์€ ๋ณด๊ธฐ์—” ๋‹จ์ˆœํ•˜์ง€๋งŒ, ์‹ค์ œ๋กœ ์ค‘๊ฐ„ ๋ฐฐ์—ด์ด ํ•œ ๋ฒˆ ๋” ๋งŒ๋“ค์–ด์ ธ ์„ฑ๋Šฅ ๋‚ญ๋น„๊ฐ€ ์ƒ๊ธด๋‹ค.
Array.from(iterable, mapFn)์€ ๋ณ€ํ™˜ + ๋งคํ•‘์„ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•ด ํšจ์œจ์ ์ด๋‹ค.


7. ๋ฐฐ์—ด ๋ฉ”์†Œ๋“œ ์ฝœ๋ฐฑ์—๋Š” return์„ ๋ช…์‹œ โ€‹

eslint: array-callback-return

๋งŒ์•ฝ ํ•จ์ˆ˜๊ฐ€ ๋‹จ์ผ ํ‘œํ˜„์‹์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ตฌ๋ฌธ์ด๋ผ๋ฉด return์„ ์ƒ๋žตํ•ด๋„ ๋œ๋‹ค.

js
// good
// ์—ฌ๋Ÿฌ ์ค„ ๋ธ”๋ก ๋‚ด๋ถ€์—์„œ๋Š” ๋ฐ˜๋“œ์‹œ return ์‚ฌ์šฉ
[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});

// good
// ๋‹จ์ผ ํ‘œํ˜„์‹์ด๋ผ๋ฉด return ์ƒ๋žต ๊ฐ€๋Šฅ (์•”๋ฌต์  ๋ฐ˜ํ™˜)
[1, 2, 3].map((x) => x + 1);

// bad
// return์ด ์—†์œผ๋ฏ€๋กœ reduce์˜ acc๊ฐ€ undefined๊ฐ€ ๋˜์–ด๋ฒ„๋ฆผ
[
  [0, 1],
  [2, 3],
  [4, 5],
].reduce((acc, item, index) => {
  const flatten = acc.concat(item); // ๊ธฐ์กด ๋ฐฐ์—ด์— ํ˜„์žฌ ๋ฐฐ์—ด์„ ํ•ฉ์นจ
  acc[index] = flatten; // return์ด ์—†์–ด์„œ acc ๊ฐ’์ด undefined๋กœ ๋ณ€ํ•จ
});

// good
// ๊ฐ ๋‹จ๊ณ„๋งˆ๋‹ค ๋ฐ˜ํ™˜๊ฐ’์„ ๋ช…์‹œํ•ด์•ผ ๋‹ค์Œ ๋ฐ˜๋ณต์œผ๋กœ ์ „๋‹ฌ๋จ
[
  [0, 1],
  [2, 3],
  [4, 5],
].reduce((acc, item, index) => {
  const flatten = acc.concat(item);
  acc[index] = flatten;
  return flatten;
});

// bad
// else๋ฌธ์— return์ด ์žˆ์ง€๋งŒ if ์•ˆ์ชฝ์€ ๋ณต์žกํ•˜๊ฒŒ ์ค‘์ฒฉ๋˜์–ด ์ฝ๊ธฐ ์–ด๋ ค์›€
inbox.filter((msg) => {
  const { subject, author } = msg;
  if (subject === 'Mockingbird') {
    return author === 'Harper Lee';
  } else {
    return false;
  }
});

// good
// early return์œผ๋กœ ๊น”๋”ํ•˜๊ฒŒ ์ž‘์„ฑ
inbox.filter((msg) => {
  const { subject, author } = msg;
  if (subject === 'Mockingbird') {
    return author === 'Harper Lee';
  }

  return false;
});
  • ์ฝœ๋ฐฑ์—์„œ return์„ ์ƒ๋žตํ•˜๋ฉด undefined๊ฐ€ ๋ฐ˜ํ™˜๋ผ ๋ฒ„๊ทธ๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค.

8. ๋ฐฐ์—ด์ด ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ ์žˆ๋‹ค๋ฉด ๋ฐฐ์—ด์„ ์—ฐ ์ดํ›„์™€ ๋‹ซ๊ธฐ ์ด์ „์— ์ค„๋ฐ”๊ฟˆ์„ ์šฐ์„  โ€‹

js
// good
const arr = [
  [0, 1],
  [2, 3],
  [4, 5],
];

const objectInArray = [
  {
    id: 1,
  },
  {
    id: 2,
  },
];

const numberInArray = [1, 2];
  • ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์นœ ๋ฐฐ์—ด์€ [ ์ดํ›„์™€ ] ์ด์ „์— ์ค„๋ฐ”๊ฟˆ์„ ์ถ”๊ฐ€ํ•œ๋‹ค.
  • ํ•œ ์ค„ ๋ฐฐ์—ด์€ [1, 2, 3]์ฒ˜๋Ÿผ ์œ ์ง€ํ•œ๋‹ค.


๊ทœ์น™์›์น™
๋ฆฌํ„ฐ๋Ÿด ์ƒ์„ฑ[]๋Š” ๋ช…ํ™•ํ•˜๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅ
๊ฐ’ ์ถ”๊ฐ€push()๋กœ ์˜๋„๋ฅผ ๋“œ๋Ÿฌ๋ƒ„
๋ฐฐ์—ด ๋ณต์‚ฌ...spread๋กœ ๋ถˆ๋ณ€์„ฑ ์œ ์ง€
iterable ๋ณ€ํ™˜์ „๊ฐœ(...) ์‚ฌ์šฉ
array-like ๋ณ€ํ™˜Array.from() ์‚ฌ์šฉ
๋งคํ•‘Array.from(obj, mapFn)
์ฝœ๋ฐฑ ๋ฐ˜ํ™˜return ๋ช…์‹œ
ํฌ๋งทํŒ…์ค„๋ฐ”๊ฟˆ ๊ทœ์น™ ์œ ์ง€