Array.from을 통한 배열의 초기화

Tei·2020년 8월 9일
38

Toast 에서 번역한 테트리스 만들기 https://ui.toast.com/weekly-pick/ko_20191216 글을 보다 Array.from의 생소한 활용법을 발견했습니다.

Array.from 을 이용하여 빈 배열을 초기화 하는 코드

Array.from(
  {length: 20},
  () => Array(10).fill(0)
);

직관적으로 0 으로 초기환된 20x10 짜리 2차원 배열을 리턴한다는 것을 알 수 있었지만, 다소 생소한 표현법이어서 어떻게 동작하는지 한번 알아보았습니다.

Array.from

Array.from 은 유사 배열 객체를 배열로 바꾸는데 자주 사용했었는데요, MDN 에 나와있는 대표적인 사용 예는 다음과 같습니다.

1. 
Array.from('Tei');
//["T", "e", "i"]

2.
Array.from([1, 2, 3], x => x + x);
//[2, 4, 6]

먼저 1 의 예시는 문자열을 인자로 받아 이를 배열로 반환해 주고 있습니다.

오늘 주제에 해당하는 것은 2 의 예시인데요, 첫번째 인자로 배열을, 두번째 인자로 각각의 배열에 적용할 함수를 건내주고 있습니다.

자바스크립트 배열의 length

그렇다면 다시 위의 예시를 볼까요?

Array.from(
  {length: 20}, // 유사배열
  () => Array(10).fill(0) // 각각의 배열에 적용할 함수
);

이제 점점 감이 잡히네요, 역시 직관적으로 {length:20} 이라는 것이 유사배열로 인식되고 있고, 그 각각의 요소에 10 개만큼 0 으로 채워주고 있다는 사실을 알 수 있습니다.

그렇다면 왜 {length:20} 은 유사배열인 것일까요? 아무리 봐도 객체인데 말입니다.

그 비일은 자바스크립트 배열의 구조에서 알 수 있습니다.

자바스크립트에서 배열은 object 이기 때문입니다.

[*]
그렇다고 object 와 배열이 동치인 것은 아닙니다.
object 의 __proto__Object.prototype이고
배열의 __proto__array.prototype 입니다. (계속 올라가다보면 Object.prototype 이 나옵니다, 즉 좀더 많은 기능을 가지고 있는 Object라고 볼 수 있겠습니다)

이제 대부분의 궁금증이 해소되었습니다. 배열은 사실 length 라는 속성을 가진 object 이고, 그렇다면 반대로 object 에 length 속성을 넣어주게 되면 마치 배열처럼 인식된다는 것이죠.

[*]
하지만 역시나 length 속성을 추가한 object 가 배열과 같다는 이야기는 아닙니다. 배열의 프로토타입인 Array 에는 배열로서 동작하기 위한 다른 메소드들이 담겨있기 때문이죠.

바로 여기에 담겨있는데요, __proto__:Array(0) 의 정체를 한번 볼까요?

그렇습니다. 예상과 같이 Array 메소드들과 Symbol.iterator 등이 담겨있습니다.
즉 이터러블 프로토콜을 따르고, length 속성이 있고 Array 메소드들이 있는 Object가 바로 배열이다 라고 할 수 있겠네요.

결론.

  • 자바스크립트에서 배열은 object 이다
  • object 에 Array 메소드들과 iterator, length 속성을 넣어준것이 배열이다
  • Array.from 은 유사 배열을 배열로 만들어주는 메소드이고, 두번째 인자로 각각의 유사배열에 전달할 함수를 넘길 수 있다.
  • 그렇기때문에 Array.from의 첫번째 인자로 {length:20} 같은것을 건내준다면 길이 20짜리 배열로 인식하여 위의 코드가 잘 동작한다.
profile
Being a service developer

1개의 댓글

comment-user-thumbnail
2021년 9월 7일

자바스크립트에서 객체란 정말 오묘하군요! Array.from의 첫번째 인자로 배열의 속성과 값을 넣어주면 배열부터 동작한다는 점을 처음 알고, 감탄했습니다! 좋은 글 감사합니다^^

답글 달기