본문 바로가기
Programming/자바스크립트

[자바스크립트] 유사 배열 객체

by 코딩하는 랄로 2023. 11. 3.
728x90

배열의 구조

유사 배열에 대해서 알아보기 전에 먼저 자바스크립트에서 배열이 어떤 구조를 가지고 있는지 살펴보겠다. 이를 알아보기 위해서 브라우저의 콘솔 창에 배열은 선언한 뒤 출력해보면 다음과 같이 배열의 구조를 볼 수 있다.

 

자바스크립트에서 배열은, 객체의 한 종류이기 때문에 배열의 구조를 파헤치면 객체의 형태를 띄는 것을 볼 수 있다. 이를 자세히 보면, 인덱스와 해당 요소가 key, value 쌍으로 구성되고, 아래의 length 프로퍼티를 가진다. 그리고 배열이기 때문에 prototype으로 배열의 메소드를 상속 받는 구조를 가지는 것 또한 확인할 수 있다.

 

이를 정리하면 배열의 구조는 아래의 구성요소를 가진다.

  • 인덱스(key) : 요소값(value) 
  • length 프로퍼티
  • Array prototype

 

 

유사 배열 객체

유사 배열 객체란, 객체지만 배열과 유사한 구조를 가지는 객체를 의미한다. 즉, 위에서 살펴본 배열의 구조와 비슷하게 생긴 객체를 자바스크립트는 유사 배열 객체라고 인식하는 것이다.

 

그러기 위해서는 배열의 구성요소 중 아래의 프러퍼티들을 객체가 가지고 있어야 한다.

  • 인덱스(key) : 요소값(value) 
  • length 프로퍼티

객체 안의 프로퍼티 이름이 0 부터 차례대로 증가하고, length 프로퍼티를 가지고 있으면, 자바스크립트는 해당 객체를 유사 배열 객체라고 인식하는 것이다. (숫자는 0부터 증가하지 않아도 되지만, 0부터 세는 것을 권장...) 

 

 

 

유사 배열 객체 생성

위의 유사 배열 객체의 조건만 만족한다면, 언제든지 유사 배열 객체를 생성할 수 있다. 

// 유사 배열 객체 생성
// index : value
// length <= 중요
const arr = {
    0 : 'java',
    1 : 'javascript',
    2 : 'python',
    length : 3
}

// 타입은?
console.log(Array.isArray(arr)); //false
console.log(arr.constructor.name === 'Object'); //true

 

위의 코드를 통해 알 수 있듯이, 유사 배열 객체는 배열과 유사한 구조를 가지지만 배열 아닌 일반 객체인 것을 알 수 있다. 그렇다면 결국 객체인데 유사 배열 객체은 어떠한 차이점을 가지고 있을까?

 

 

 

Array.from

유사 배열 객체과 일반 객체와는 달리 Array 객체의 정적 메소드인 from 메소드를 통해서 언제든지 배열로 사용할 수 있다. from 메소드는 다음과 같은 구문을 가진다.

Array.from(arrayLike, mapFn, thisArg => return Array.instance

 

파라미터 설명
arrayLike 유사 배열 객체
mapFn [optional]배열의 모든 요소에 대해 호출하는 콜백함수로, 해당 함수를 통해 반환되는 값이 배열에 추가됨. (element, index)를 인수로 사용할 수 있음
thisArg [optional] mapFn에서 사용할 this를 지정

 

이를 이용한 예제 코드이다.

// Array.from(arrayLike)
const arr = {
    0 : 'java',
    1 : 'javascript',
    2 : 'python',
    length : 3
}

// 반환값이 배열 객체이기 때문에,
console.log(Array.isArray(Array.from(arr)));  //true

// 배열 메소드 바로 사용 가능
Array.from(arr).forEach(el => console.log(el))
/*
java
javascript
python
*/


// Array.from(arrayLike, mapFn)
// mapFn => 배열의 map 메소드와 똑같은 기능
const arr2 = Array.from(arr, function(el) { // <== arrow function도 가능
    return `Hi, ${el}`
}).forEach(el => console.log(el))
/*
Hi, java
Hi, javascript
Hi, python
*/

 

 

 

DOM 에서의 유사 배열 객체

자바스크립트에서 DOM을 다루다 보면 유사 배열 객체를 반환하는 메소드가 종종 있다. 아래의 코드를 살펴보자.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul class="list">
        <li>1</li>
        <li>2</li>
        <li>3</li>
        <li>4</li>
    </ul>
</body>
<script>
    const list = document.getElementsByTagName('li');
    console.log(list);
</script>
</html>

 

html에 목록을 생성시키고 script를 통해 목록의 아이템에 getElementsByTagName을 통해 다 불러온다면, 어떠한 형태로 list에 저장되었는지 알아보기 위해 콘솔 창에 출력 시켜 보았다.

 

그 결과, 위와 같이 유사 배열 객체로 저장된 것을 볼 수 있다. 이를 배열로 변환하여 목록의 아이템을 1씩 증가시키는 코드를 작성한다고 했을 때 아래와 같이 작성할 수 있다.

<script>
    const list = document.getElementsByTagName('li');
    Array.from(list).forEach(el => el.innerHTML = Number(el.innerText.trim()) + 1)
</script>

 

잘 동작한 것을 볼 수 있다.

결과

 

이처럼, 유사 배열 객체는 언제든지 배열로 변환하여 배열의 다양하고 유용한 메소드를 사용할 수 있고 이로 인하여 DOM을 다루기도 쉬워지고 코드도 간결해진다는 장점이 있다.

 

이러한 장점을 활용하기 위해서는, 해당 메소드가 유사 배열 객체를 리턴하는지 잘 알아볼 필요가 있다. (유사 배열 객체에 대해서 잘 모르고 해당 메소드가 그를 반환하는지 잘 모르는 경우가 꽤 있기 때문에...)

728x90