Toast 에서 번역한 테트리스 만들기 https://ui.toast.com/weekly-pick/ko_20191216
글을 보다 Array.from의 생소한 활용법을 발견했습니다.
Array.from(
{length: 20},
() => Array(10).fill(0)
);
직관적으로 0 으로 초기환된 20x10 짜리 2차원 배열을 리턴한다는 것을 알 수 있었지만, 다소 생소한 표현법이어서 어떻게 동작하는지 한번 알아보았습니다.
Array.from
은 유사 배열 객체를 배열로 바꾸는데 자주 사용했었는데요, MDN 에 나와있는 대표적인 사용 예는 다음과 같습니다.
1.
Array.from('Tei');
//["T", "e", "i"]
2.
Array.from([1, 2, 3], x => x + x);
//[2, 4, 6]
먼저 1 의 예시는 문자열을 인자로 받아 이를 배열로 반환해 주고 있습니다.
오늘 주제에 해당하는 것은 2 의 예시인데요, 첫번째 인자로 배열을, 두번째 인자로 각각의 배열에 적용할 함수를 건내주고 있습니다.
그렇다면 다시 위의 예시를 볼까요?
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가 바로 배열이다 라고 할 수 있겠네요.
자바스크립트에서 객체란 정말 오묘하군요! Array.from의 첫번째 인자로 배열의 속성과 값을 넣어주면 배열부터 동작한다는 점을 처음 알고, 감탄했습니다! 좋은 글 감사합니다^^