JavaScript/js 문법

js 배열 만들기 : Array.from(), Array.fromAsync(), Array.isArray(), Array.of()

GREEN나무 2025. 4. 11. 12:35
728x90

 

JavaScript에서 제공하는 Array 관련 정적 메소드들은 배열 생성 및 판별, 그리고 변환 과정에서 매우 유용하게 활용될 수 있습니다. 

 

목차

  1. Array.from()
    • 개요
    • 구문 및 매개변수
    • 반환 값과 동작 방식
    • 추가 설명
    • 기본 예시 코드
    • 응용 예시 코드
  2. Array.fromAsync()
    • 개요
    • 구문 및 매개변수
    • 반환 값과 동작 방식
    • 추가 설명
    • 기본 예시 코드
    • 응용 예시 코드
  3. Array.isArray()
    • 개요
    • 구문 및 매개변수
    • 반환 값과 동작 방식
    • 추가 설명
    • 기본 예시 코드
    • 응용 예시 코드
  4. Array.of()
    • 개요
    • 구문 및 매개변수
    • 반환 값과 동작 방식
    • 추가 설명
    • 기본 예시 코드
    • 응용 예시 코드

1. Array.from()

개요

Array.from() 메소드는 반복 가능한(iterable) 객체나 배열과 유사(array-like)한 객체로부터 새 배열 인스턴스를 생성하며, 객체 내 각 요소를 얕게 복사한다. 또한 선택적으로 매핑 함수를 사용해 각 요소를 가공한 후 새로운 배열을 생성할 수 있다.

구문 및 매개변수

Array.from(arrayLike)
Array.from(arrayLike, mapFn)
Array.from(arrayLike, mapFn, thisArg)
  • arrayLike: 반복 가능한(iterable) 객체나 배열과 유사한 객체(길이 속성과 인덱스 속성을 가진 객체)
  • mapFn (선택적): 배열의 각 요소에 대해 실행될 함수. 두 개의 인자(현재 요소와 인덱스)를 받아 그 반환 값을 새 배열에 추가한다.
  • thisArg (선택적): mapFn 실행 시 참조될 this 값.

반환 값과 동작 방식

  • 반환 값: 새로 생성된 Array 인스턴스
  • 동작 방식:
    • 배열 또는 반복 가능한 객체의 요소를 순회하며 값을 복사하여 새 배열에 추가한다.
    • mapFn이 제공되면 각 요소에 대해 함수를 적용한 후 그 결과를 배열에 담는다.
    • 배열과 유사 객체에서 누락된 인덱스의 경우 결과 배열에서는 해당 인덱스가 undefined로 채워진다.

추가 설명

  • 용도:
    • Iterable 객체(예: 문자열, Map, Set 등)를 일반 배열로 변환할 때 유용하다.
    • 배열과 유사한 객체(예: arguments 객체, DOM의 NodeList 등)를 배열로 변환할 때 사용한다.
  • 특징:
    • 매핑 함수(mapFn)를 사용해 배열 생성 시 각 요소를 변환할 수 있다.
    • 중간 배열을 생성하지 않고 바로 결과 배열에 값들을 할당하므로 메모리 사용 측면에서 이점이 있다.
  • 주의 사항:
    • TypedArray 등에서 중간 배열 없이 값을 변환하는 데 유용하며, 하위 클래스에서 호출 시 하위 클래스의 인스턴스를 반환할 수 있다.

기본 예시 코드

문자열을 배열로 변환하는 예시이다.

console.log(Array.from("foo"));
// 출력: [ "f", "o", "o" ]

응용 예시 코드

배열의 각 요소를 두 배로 만드는 예제이다.

console.log(Array.from([1, 2, 3], (x, i) => x + x));
// 출력: [ 2, 4, 6 ]

추가 예제로, NodeList를 배열로 변환해 이미지 요소의 src 속성을 추출하는 방법이다.

// document.querySelectorAll로 NodeList를 받아온 후 배열로 변환
const images = document.querySelectorAll("img");
const sources = Array.from(images, image => image.src);
// 'http://'로 시작하는 이미지 URL만 필터링
const insecureSources = sources.filter(link => link.startsWith("http://"));

2. Array.fromAsync()

개요

Array.fromAsync() 메소드는 비동기(iterable) 객체, 일반 iterable 객체 또는 배열과 유사 객체를 사용해 새 배열 인스턴스를 생성하는 메소드이다.
각 요소에 대해 await 처리가 적용되며, 최종 결과 배열을 담은 Promise를 반환한다.

구문 및 매개변수

Array.fromAsync(arrayLike)
Array.fromAsync(arrayLike, mapFn)
Array.fromAsync(arrayLike, mapFn, thisArg)
  • arrayLike: 비동기 iterable, 일반 iterable 또는 배열과 유사 객체
  • mapFn (선택적): 각 요소에 대해 호출될 비동기 함수로, 내부적으로 입력 값과 반환 값을 모두 await 처리한다.
  • thisArg (선택적): mapFn 실행 시 참조될 this 값.

반환 값과 동작 방식

  • 반환 값: 결과 배열 인스턴스를 담은 Promise
  • 동작 방식:
    • 비동기 iterable 객체의 경우 for await...of와 유사하게 순차적으로 각 요소를 처리한다.
    • 동기 iterable인 경우에도 각 요소를 await 처리하여 결과 배열에 추가한다.
    • mapFn이 제공되면 각 요소에 대해 비동기 처리를 한 후 배열에 담는다.

추가 설명

  • 용도:
    • 비동기 작업의 결과를 배열로 모으거나, 비동기적으로 값을 변환해 배열로 저장할 때 사용한다.
  • 특징:
    • 요소를 하나씩 순차 처리하므로, 작업 순서가 보장된다.
  • 주의 사항:
    • Promise.all()과는 달리 순차적으로 처리되므로, 경우에 따라 전체 처리 시간이 길어질 수 있다.

기본 예시 코드

비동기 제너레이터로 생성한 값을 배열로 변환하는 예시이다.

const asyncIterable = (async function* () {
  for (let i = 0; i < 5; i++) {
    await new Promise(resolve => setTimeout(resolve, 10 * i));
    yield i;
  }
})();

Array.fromAsync(asyncIterable).then(array => console.log(array));
// 출력: [0, 1, 2, 3, 4]

응용 예시 코드

배열 내의 Promise를 처리하고, 각 요소를 두 배로 만드는 매핑 함수를 적용하는 예제이다.

function delayedValue(v) {
  return new Promise(resolve => setTimeout(() => resolve(v), 100));
}

Array.fromAsync(
  [delayedValue(1), delayedValue(2), delayedValue(3)],
  async (element, index) => {
    const value = await element;
    return delayedValue(value * 2);
  }
).then(array => console.log(array));
// 출력: [2, 4, 6]

또한, Promise.all()과 처리 시간을 비교하는 예제도 참고할 만하다.

function* makeIterableOfPromises() {
  for (let i = 0; i < 5; i++) {
    yield new Promise(resolve => setTimeout(resolve, 100));
  }
}

(async () => {
  console.time("Array.fromAsync() time");
  await Array.fromAsync(makeIterableOfPromises());
  console.timeEnd("Array.fromAsync() time");

  console.time("Promise.all() time");
  await Promise.all(makeIterableOfPromises());
  console.timeEnd("Promise.all() time");
})();

3. Array.isArray()

개요

Array.isArray() 메소드는 전달된 값이 실제 배열(Array)인지 판별한다.
프로토타입 체인에 포함된 객체라도 실제 Array 생성자를 통해 생성된 경우에만 true를 반환하며, 배열과 유사하지만 Array가 아닌 객체는 false를 반환한다.

구문 및 매개변수

Array.isArray(value)
  • value: 배열 여부를 판별할 대상 값

반환 값과 동작 방식

  • 반환 값: 실제 Array 인스턴스이면 true, 그렇지 않으면 false
  • 동작 방식:
    • 내부적으로 Array 생성자에 의해 초기화된 비공개 속성을 확인하여 배열 여부를 판별한다.
    • TypedArray와 같이 배열처럼 보이나 실제 Array가 아닌 경우 false로 판단한다.

추가 설명

  • 용도:
    • 값이 실제 배열인지 확실하게 확인할 필요가 있을 때 사용한다.
    • 다른 실행 환경(예: iframe)에서 생성된 배열 객체도 올바르게 판별할 수 있다.
  • 비교:
    • instanceof Array와 달리, 프로토타입 체인에 의존하지 않으므로 더 정확한 판별이 가능하다.

기본 예시 코드

배열과 배열이 아닌 값을 판별하는 기본 예제이다.

console.log(Array.isArray([1, 3, 5]));       // 출력: true
console.log(Array.isArray("[]"));            // 출력: false
console.log(Array.isArray(new Array(5)));    // 출력: true
console.log(Array.isArray(new Int16Array([15, 33]))); // 출력: false

응용 예시 코드

다음 예제는 iframe 내에서 생성된 배열 객체를 판별하는 예이다.

const iframe = document.createElement("iframe");
document.body.appendChild(iframe);
const iframeArrayConstructor = window.frames[window.frames.length - 1].Array;
const arr = new iframeArrayConstructor(1, 2, 3);

console.log(Array.isArray(arr));       // 출력: true
console.log(arr instanceof Array);     // 출력: false (다른 Realm의 Array 객체)
// iframe 제거
document.body.removeChild(iframe);

4. Array.of()

개요

Array.of() 메소드는 가변 인자(arguments)를 받아 새 배열 인스턴스를 생성한다.
특히 단일 인자일 때 해당 인자 하나를 요소로 갖는 배열을 생성함으로써, Array 생성자와의 차이를 명확히 한다.
예를 들어, Array.of(7)은 [7]을 반환하고, Array(7)은 길이가 7인 빈 배열(실제로는 7개의 empty slot)을 생성한다.

구문 및 매개변수

Array.of()
Array.of(element1)
Array.of(element1, element2)
Array.of(element1, element2, …, elementN)
  • element1, …, elementN: 새 배열의 요소로 포함될 값들

반환 값과 동작 방식

  • 반환 값: 전달된 인자를 요소로 하는 새 배열 인스턴스
  • 동작 방식:
    • 단일 인자라도 해당 인자 자체를 배열의 요소로 포함하여 배열을 생성한다.
    • 만약 this 값이 생성자 함수로 동작할 수 있다면, 그 생성자를 사용해 배열(또는 유사 배열 객체)을 생성한다.

추가 설명

  • 용도:
    • 전달된 모든 인자를 동일한 방식으로 배열로 만들고자 할 때 사용한다.
    • 사용자 정의 생성자에 대해 Array.of() 메소드를 호출해 배열과 유사한 객체를 생성할 수 있다.
  • 특징:
    • 단일 값 전달 시에도 명확하게 배열을 생성할 수 있다는 점이 Array 생성자와의 차이점이다.
    • 하위 클래스에서 상속받은 경우, 그 클래스의 인스턴스를 반환할 수 있다.

기본 예시 코드

단일 값과 여러 값을 인자로 전달하여 배열을 생성하는 예제이다.

console.log(Array.of("foo", 2, "bar", true));
// 출력: [ "foo", 2, "bar", true ]

console.log(Array.of(7));
// 출력: [7]

console.log(Array.of());
// 출력: []

응용 예시 코드

사용자 정의 생성자 함수에 대해 Array.of() 메소드를 호출하는 예제이다.

function NotArray(len) {
  console.log("NotArray 생성자 호출, 길이:", len);
  for (let i = 0; i < arguments.length; i++) {
    this[i] = arguments[i];
  }
  this.length = arguments.length;
}

const customArray = Array.of.call(NotArray, 1, 2, 3);
console.log(customArray);
// 출력:
// NotArray 생성자 호출, 길이: 3
// { '0': 1, '1': 2, '2': 3, length: 3 }

또한, this 값이 생성자 함수가 아닐 경우 기본 Array 인스턴스를 반환하는 예제이다.

console.log(Array.of.call({}, 1)); // 출력: [ 1 ]

마무리

JavaScript에서 제공하는 Array 관련 정적 메소드들은 배열 및 유사 배열 객체의 생성, 판별, 비동기 처리에 있어서 매우 유용하다.
각 메소드의 개념, 사용법, 매개변수, 반환 값 및 동작 방식을 충분히 이해하고, 기본 예시와 응용 예시 코드를 통해 다양한 상황에 맞게 활용하면 좋다.
이 자료를 블로그 게시글에 활용하면 독자들이 개념을 명확하게 이해하고 실무에 적용하는 데 도움이 될 것이다.


출처
Array.from()
Array.fromAsync() 
Array.isArray()
Array.of()