내용이 안 보인다면 쿠키/캐시를 지우고 새로고침 하세요!
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

게시글

강좌57 - JavaScript - 7달 전 등록 / 6달 전 수정

배열과 유사배열

조회수:
0
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ
이 블로그는 광고 클릭 수익으로 운영됩니다!
괜찮으시다면 광고 차단을 풀어주세요 ㅠㅠ

안녕하세요. 이번 시간에는 배열과 유사배열에 대해서 살펴보겠습니다.

배열은 다들 아실겁니다. 그런데 유사배열은 잘 모르는 입문자분들이 많이 계십니다. 한 번 둘의 차이를 알아봅시다.

var array = [1, 2, 3];
array; // [1, 2, 3]
var nodes = document.querySelectorAll('div'); // NodeList [div, div, div, div, div, ...]
var els = document.body.children; // HTMLCollection [noscript, link, div, script, ...]

nodes와 els는 프론트엔드 개발을 하다보면 많이 접하는 친구들이죠. 위 예제에서 array는 배열이고, nodes와 els는 유사배열입니다. 둘의 차이를 아시겠나요? 겉만 봐서는 잘 모릅니다. 둘 다 비슷하게 []로 감싸져 있거든요. Array.isArray 메서드(배열인지를 판단해주는 메서드)를 사용해서 뭐가 배열인지 확인해보겠습니다.

Array.isArray(array); // true
Array.isArray(nodes); // false
Array.isArray(els); // false

직접 배열 리터럴로 선언한 array만 배열입니다. 비슷한 방법으로, array instanceof Array로도 판단할 수 있습니다.

nodes나 els처럼 []로 감싸져있지만 배열이 아닌 친구들을 유사배열이라고 부릅니다. 어떻게 이런 친구들이 만들어지는지 알아봅시다.

var yoosa = {
  0: 'a',
  1: 'b',
  2: 'c',
  length: 3
};

yoosa 객체가 바로 유사배열입니다. 키가 숫자고, length라는 속성을 가지고 있습니다. 배열도 객체라는 성질을 이용한 트릭입니다. 배열처럼 yoosa[0], yoosa[1], yoosa.length같은 것을 모두 활용할 수 있습니다.

배열과 유사배열을 구분해야 하는 이유는, 유사배열의 경우 배열의 메서드를 쓸 수 없기 때문입니다.

array.forEach(function(el) { console.log(el); }); // 1, 2, 3
els.forEach(function(el) { console.log(el); }); // Uncaught TypeError: els.forEach is not a function

els에 forEach같은 배열 메서드를 사용하면 에러가 발생합니다. (nodes는 프로토타입에 forEach가 있어서 됩니다.) 배열이 아니므로 발생하는 것입니다. 이럴 때 메서드를 빌려 쓰는 방법이 있습니다. 배열 프로토타입에서 forEach 메서드를 빌려오는 것이죠. 바로 call이나 apply입니다. 이 강좌에서 설명했습니다.

Array.prototype.forEach.call(nodes, function(el) { console.log(el); });
[].forEach.call(els, function(el) { console.log(el); });

이제 유사배열에도 forEach를 사용할 수 있습니다. map이나 filter, reduce 등의 다른 배열 메서드도 사용 가능합니다.

최신 자바스크립트에서는 Array.from으로 더 간단하게 할 수 있습니다.

Array.from(nodes).forEach(function(el) { console.log(el) });

자주 보는(ES6에서는 더 이상 안 보이지만) 유사배열이 하나 더 있습니다. function의 arguments입니다. 함수선언문에 넣은 인자 목록을 표시하죠.

function arrayLike() {
  console.log(arguments);
}
arrayLike(4, 5, 6); // Arguments [4, 5, 6, callee, Symbol]

역시 forEach같은 배열 메서드를 쓸 수 없으므로 문제가 됩니다. 위에서 설명한 방법을 적용해야 합니다.

function arrayLike() {
  console.log(arguments);
  [].forEach.call(arguments, function(el) { console.log(el) });
}
arrayLike(4, 5, 6);

유사배열, 별 거 아니죠? []로 감싸져 있다고 다 같은 배열이 아니라는 것과, Array.isArray로 판별하는 방법, 배열 프로토타입에서 메서드를 빌려쓰는 방법에 대해서 알아두시면 좋습니다! 유사배열과 자주 만나는 프론트엔드에서는 필수입니다!

다음 시간에는 this에 대해 좀 더 자세하게 알아보겠습니다.

투표로 게시글에 관해 피드백을 해주시면 많은 도움이 됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright © 2016- 무단 전재 및 재배포 금지

댓글

5개의 댓글이 있습니다.
한 달 전
Nodejs 교과서 7장 sequelize.js 첫 문장이 [].forEach.call(....로 시작해서 멘붕왔는데 너무 친절한 설명 감사합니다
2달 전
안녕하세요, 잘 봤습니다. 그런데 일반 객체와 유사배열을 구별할 방법은 없을까요?
2달 전
유사배열도 일반 객체이기 때문에 구별하기 힘듭니다. 배열과는 구별 가능합니다.
7달 전
덕분에 유사배열이란 걸 알게되었네요 감사합니당ㅎㅎㅎㅎ
7달 전
좋은내용이네요 잘봤습니다.
7달 전
안녕하세요, 질문이 있습니다. 배열과 유사배열을 구분해야 하는 이유는, 유사배열의 경우 배열의 메서드를 쓸 수 없기 때문이라고 하셨는데, 이제 유사배열에도 forEach를 사용할 수 있다면 배열과 유사배열을 구분지을 필요가 없다는 거 아닌가요?
7달 전
아니죠. 구분지었기 때문에 forEach를 배열에서 빌려와 사용한겁니다. 반대로 생각하셔야합니다.