본문 바로가기
이론/Frontend

자바스크립트의 Array

by 유세지 2022. 3. 22.

이번 포스팅 주제는 자바스크립트의 Array 객체입니다. 자바스크립트를 시작했다면 누구나 한 번쯤은 써봤을 흔한 빌트인 객체이지만, 저는 아직 Array의 사용법에 대해 잘 모르고 있었습니다. 얼마 전 다양한 메서드들을 활용해보며 공부할 기회가 있었는데, 이 참에 잊어버리지 않도록 정리하게 되었습니다.

 

선언

Array의 선언 방법에는 두 가지가 있습니다. 배열 내용을 직접 선언하는 리터럴 방식과, new 키워드를 이용하는 생성자 방식이 그것입니다. 먼저 리터럴 방식입니다.

 

const arr = ["literal", "way"];

 

배열 기호인 대괄호[] 안쪽에 내용을 직접 입력해주는 것으로 Array를 생성할 수 있습니다.

 

다음은 생성자 방식입니다.

 

const arr = new Array("constructor", "way");

 

new 키워드와 함께 생성자의 인수로 내용을 넣어줌으로써 Array를 생성할 수 있습니다.

생성자 방식에서는 인수의 갯수와 타입에 특정 조건을 만족하면 다르게 동작합니다.

 

const arr = new Array(123);

 

위처럼 인수가 하나뿐이며, 그 인수가 0에서 2^31-1 사이의 정수일 경우 그 값만큼의 길이를 가진 Array를 생성하게 되며, 배열의 각 요소는 null 또는 undefined가 아닌 빈 슬롯(empty slot)이 됩니다. 만약 지정된 범위를 넘어가거나 정수가 아니라면, RangeError를 반환합니다.

 

만약 길이가 123이 아닌 정수형 값 123 하나를 갖는 배열을 생성하고 싶다면, Array.of() 를 이용하면 됩니다.

 

Array(123); // [ , , , , , ... , ]
Array.of(123); // [123]

 

속성

Array.prototype.length

배열이 가진 원소의 수를 나타냅니다. 실제로 원소가 있지 않은 상태(빈 값)라도, 위의 생성자 방식으로 Array를 생성한 경우 다른 값을 가질 수 있습니다.

 

const arr = [1, 2, 3];
console.log(arr.length); // 3

 

메서드

다음은 Array에서 사용할 수 있는 메서드들이며, 이 글을 쓰게 된 계기가 된 부분이기도 합니다. 정말 많은 메서드들이 준비되어 있었지만 실제로 사용한 메서드는 극히 일부였기에, 효율적인 코드를 작성하기 위해 꼭 알고 넘어가야 했습니다.

 

 

Array.prototype.every()

배열 안의 모든 요소가 주어진 판별 함수를 통과하는지 테스트하는 메서드입니다.

모두 만족한다면 true를, 하나라도 만족하지 않으면 false를 반환하는 특성때문에 "배열 안의 요소가 모든 조건을 만족하는 경우" 를 판별할 때 많이 사용합니다.

 

예외적으로, 빈 배열에 every() 메서드를 사용하면 항상 true를 반환합니다.

 

const arr = [1, 2, 3, 4, 5];
console.log(arr.every(item => item < 10));
// true

console.log(new Array().every(item => item < 10));
// true

 

 

Array.prototype.some()

배열 안의 어떤 요소라도 주어진 판별 함수를 통과하는지 테스트하는 메서드입니다.

하나라도 만족한다면 true를, 모두 만족하지 않으면 false를 반환하는 식으로 every() 메서드와 완전히 반대로 작동하며 빈 배열에 사용하면 무조건 false를 반환합니다.

 

const arr = [1, 2, 3, 4, 5];
console.log(arr.some(item => item > 10));
// false

console.log(new Array().some(item => item > 10));
// false

 

some() 메서드 또한 "배열 안의 요소가 모든 조건을 만족하는 경우" 를 판별할때 사용하는 경우가 많은데, 이는 드 모르간의 법칙에 의해 some() 메서드를 사용하는 것이 더 효율적인 경우가 있기 때문입니다.

 

주어진 조건 중 하나라도 만족한다면 비교를 멈추고 true를 반환하는 특성을 이용하여, 중간에 만족하지 않는 조건이 있는 경우 끝까지 순회해서 모두 만족하는지 확인해야 하는 every() 메서드보다 적은 작업만으로도 결과 값을 찾을 수 있게 됩니다.

 

// good
console.log(new Array().every(item => item < 10));

// but... may be better in sometimes
console.log(!new Array().some(item => item >= 10));

 

 

Array.prototype.filter()

주어진 함수의 테스트를 통과하는 모든 요소를 모아 새로운 배열로 반환하는 메서드입니다.

특정 조건들을 함수로 만들고, 이 함수들을 filter() 에 인자로 넘겨주어 조건에 만족하는 요소들로 이루어진 배열을 쉽게 생성해 줄 수 있습니다.

 

const arr = [1, 2, 3, 4, 5];
console.log(arr.filter(item => item >= 3));
// Array [3, 4, 5]

 

 

Array.prototype.fill()

배열의 시작부터 끝까지 정적인 값 하나로 채우는 메서드입니다.

두 번째, 세 번째 인수로 시작 인덱스와 끝 인덱스를 지정해 줄 수 있으며 따로 지정하지 않으면 전체 값을 특정한 값으로 덮어 씌웁니다.

 

const arr = [1, 2, 3];
console.log(arr.fill(10));
// Array [10, 10, 10]

 

또는 생성자 방식으로 동적인 길이의 배열을 생성한 뒤 fill() 메서드와 다른 메서드를 함께 연계하는 것으로 다양한 곳에 응용하여 활용도를 높일 수도 있습니다.

 

// good
const customLength = 5;
new Array(customLength).fill(0).map(() => {
  ...
}

 

 

Array.prototype.includes()

배열이 특정 요소를 포함하고 있는지 판별하는 메서드입니다.

includes() 메서드를 호출한 배열이 인자로 넘겨준 값을 포함하고 있다면 true를, 포함하지 않는다면 false를 반환합니다.

 

const arr = [1, 2, 3];

console.log(arr.includes(1)); // true
console.log(arr.includes(4)); // false

 

 

Array.prototype.join()

배열의 모든 요소를 연결해 하나의 문자열로 만드는 메서드입니다.

인자로 요소들을 연결할때 사용할 구분자를 지정할 수 있으며, 빈 값으로 두면 자동으로 쉼표(,) 를 구분자로 사용합니다. 구분자 없이 요소들이 깨끗하게 연결된 문자열을 얻고 싶다면 join("") 처럼 사용할 수 있습니다.

 

요소가 null 또는 undefined 일 경우, 빈 문자열로 변환됩니다.

const arr = ['a', 'b', 'c'];
console.log(arr.join());
// "a,b,c"

console.log(arr.join(""));
// "abc"

 

저는 HTML 태그들을 저장해놓은 객체를 동적으로 여러 개 생성하여 배열이 되었을때, insertAdjacentHTML과 연계하여 많이 사용했던 것 같습니다.

 

 

Array.from()

유사 배열 객체나 반복 가능한 객체를 얕게 복사하여 새로운 Array 객체를 만드는 메서드입니다.

앞에서부터 차례대로 대상 객체, 맵핑 함수, 맵핑 함수의 this 값 을 인자로 받으며 맵핑 함수와 그의 this값은 optional한 인자입니다. 맵핑 함수는 배열의 모든 요소에 대해 호출할 수 있으므로 아래처럼 응용할 수도 있습니다.

 

const object = [true, false];
console.log(Array.from(object, value => !value));
// Array [false, true]

 

 

Array.prototype.forEach()

인자로 주어진 함수를 배열 요소 각각에 대해 실행하는 메서드입니다.

모든 배열 요소를 순회하며 함수를 적용하기 때문에 폭 넓은 사용성을 자랑하는 특징이 있습니다.

 

const arr = ["사과", "참외", "배"];
arr.forEach(item => console.log(item + "는 과일입니다."));

// "사과는 과일입니다."
// "참외는 과일입니다."
// "배는 과일입니다."

 

forEach() 메서드의 반환값은 undefined이기 때문에,

함수를 적용한 결과를 배열로 저장하려면 따로 외부 배열에 할당하는 작업을 거치거나 ...

 

 

Array.prototype.map()

... map() 메서드를 사용하면 됩니다.

map() 은 배열 내의 모든 요소에 대하여 주어진 함수를 호출하고, 그 결과를 모아 새로운 배열을 반환합니다.

 

const arr = [1, 2, 3, 4, 5];
console.log(arr.map(item => item*item));
// Array [1, 4, 9, 16, 25]

 

forEach() 메서드의 결과를 특정 배열에 담아 이용해야한다면, 처음부터 map() 메서드를 사용하여 결과 배열을 반환받아 관리하는 것이 좋습니다.

 

특히 forEach() 나 map() 처럼 배열을 순회하는 메서드를 사용할 수 있는 상황이라면, 일반적인 반복문보다는 이러한 내장 메서드를 사용하는 것이 실수를 줄이고, 가독성을 높이는 측면에서 도움이 되므로 이용하시기를 적극 권장드립니다.

 

 

 

정리

자바스크립트의 내장 객체에는 사용할 수 있는 메서드가 많이 정의되어 있고, Array는 특히나 더 그렇습니다. 이러한 메서드들을 잘 이용하여 효율적이고 좋은 코드를 짤 수 있도록 필요할때마다 잊지 않고 적용할 수 있으면 좋을 것 같습니다.

반응형

댓글