JavaScript - 배열 (Array)

베이시스·2022년 7월 14일
0

자바스크립트

목록 보기
3/3
post-thumbnail

주의: 이 내용은 필자가 JavaScript 개념을 리마인드하면서 작성한 것으로 정확하지 않은 정보가 있을 수 있습니다.

📚 어디에나 있지만 조금 특이한 그놈

배열은 어느 언어에서든 거의 빼놓지 않고 등장하는 기초적인 자료 구조입니다. 자바스크립트도 비슷하며, Array 라는 객체의 프로토타입을 통해 배열을 사용할 수 있습니다.

하지만 자바스크립트의 배열은 C-like 언어의 고정 크기 배열과는 미묘한 차이가 있습니다.
이런 차이는 어디에서 오는 것인지 배열을 이해하면서 알아보도록 합시다.


📄 배열

배열의 생성

자바스크립트에서 배열을 생성하는 방법은 크게 두 가지가 있습니다.
하나는 다른 언어에서도 보이는 리터럴, 다른 하나는 배열 생성자입니다.

배열 리터럴

const array = ['사과', '배', '감귤'];

다른 언어의 그것과 정말 비슷하지만 중괄호가 아닌(중괄호는 객체를 생성하는 괄호로 예약되어 있으니) 대괄호로 생성한다는 점이 그 차이입니다.
파이썬의 리스트를 생성하는 방법과 유사합니다.

생성자 함수 Array()

const foo = ('사과');
const bar = ('사과', '배', '감귤');

배열도 객체이기에 생성자 함수를 통해서도 만들 수 있습니다.
매개변수의 개수를 길이로 하는 배열을 생성하게 됩니다.

배열의 요소

객체에 동적으로 프로퍼티를 추가, 삭제할 수 있듯 배열에도 동적으로 요소를 추가, 삭제할 수 있습니다.
자바스크립트의 배열은 아무 위치에나 요소를 삽입, 삭제할 수 있습니다. 배열의 크기는 자동으로 확장됩니다.

const foo = ['사과', '배', '감귤'];
foo[5] = '수박'

위와 같은 코드를 실행하면 foo 배열에는 아래와 같이 요소가 들어 있게 됩니다.

['사과', '배', '감귤', undefined, undefined, '수박']

확장된 배열 사이의 빈 공간에는 실제로 원소가 위와 같이 들어있지는 않으며, 메모리 공간도 차지하지 않습니다. 해당 위치의 값을 꺼내려 하면 undefined가 나온다는 의미로 이해하시면 됩니다.

length 프로퍼티

앞서 설명한 자바스크립트 배열의 특수성 덕에 length가 가리키는 값도 조금 차이가 있습니다.
배열의 length는 배열 내 원소의 가장 큰 인덱스 + 1 입니다. 1을 더한 것은 인덱스가 0부터 시작하기 때문입니다.

length 프로퍼티는 명시적으로 값을 변경할 수도 있으며, length 값이 요소의 최대 인덱스보다 작아지면 변경된 length보다 인덱스가 큰 배열 요소는 삭제됩니다.

const foo = ['사과', '배', '감귤'];
foo.length = 2;
console.log(foo); // ['사과', '배']

배열의 프로퍼티

배열도 어쨌거나 Object.prototype를 상속받는 자바스크립트 객체이므로 배열의 요소와는 별개로 프로퍼티를 추가, 삭제할 수 있습니다.

const foo = ['사과', '배', '감귤'];
foo.name = 'fruits';
console.log(foo.name); // fruits

🧹 배열 표준 메소드

들어가기 전에, 불변성(Immutability)?

자바스크립트를 공부하다 보면 불변성(Immutability)가 자주 언급됩니다. 말 그대로 변하지 않는 것을 의미하는데, 원시 타입은 모두 불변이지만 객체는 그렇지 않습니다.

그런데 배열을 조작하는 메소드 중에는 특이하게도 불변성이 유지되는 메소드가 있습니다. 여기서는 배열의 불변성 유지 여부를 기준으로 각 메소드를 설명하겠습니다.

불변성이 정확히 무엇이고, 불변성을 유지하는 것이 중요한 이유에 대해서는 차후 별도의 포스트로 다루겠습니다.
대표적인 메소드만 정리했으며 이외에도 더 많은 배열 메소드가 있습니다.


Mutable methods

원본 배열을 수정하여 불변성이 유지되지 않는 배열 메소드입니다.

unshift / push

배열의 처음 / 마지막(length가 가리키는 위치)에 원소를 추가합니다.

const foo = ['사과', '배', '감귤'];
foo.unshift('바나나');
foo.push('수박');
console.log(foo); // [ '바나나', '사과', '배', '감귤', '수박' ]

shift / pop

배열의 처음 / 마지막 원소를 뺍니다.

const foo = ["사과", "배", "감귤"];
console.log(foo.pop()); // 감귤
console.log(foo.shift()); // 사과
console.log(foo); // [ '배' ]

fill

startIndex부터 endIndex 전까지 value로 배열을 채웁니다.
length 값을 벗어난 인덱스에 대해서는 아무 작업도 하지 않습니다.

array.fill(value, startIndex, endIndex);
let foo = ["사과", "배", "감귤"];
foo = foo.fill("바나나", 0, 2);
console.log(foo); // [ '바나나', '바나나', '감귤' ]

reverse

배열의 순서를 반전합니다.

let foo = ["사과", "배", "감귤"];
foo = foo.reverse();
console.log(foo); // [ '감귤', '배', '사과' ]

sort

배열 요소를 정렬합니다. 함수의 반환값을 통해 정렬 순서를 결정합니다.

array.sort(function);
let foo = ["사과", "배", "감귤"];
foo = foo.sort();
console.log(foo); // [ '감귤', '배', '사과' ]

splice

배열의 특정 구간을 추출하거나 해당 구간에 요소를 추가합니다.
시작 인덱스로부터 길이가 count인 부분 배열(없으면 인덱스로부터 전체)를 추출하며, item을 시작 인덱스부터 차례로 삽입합니다(인자가 있으면).

array.splice(startIndex, count?, ...items?);
let foo = ["사과", "배", "감귤"];
console.log(foo.splice(1, 2, "수박", "멜론", "참외")); // [ '배', '감귤' ]
console.log(foo); // [ '사과', '수박', '멜론', '참외' ]

Immutable methods

불변성이 유지되는 배열 메소드입니다.

forEach

배열의 각 요소에 대해 콜백 함수를 실행합니다. 반환 값은 없습니다.

const foo = [1, 2, 3, 4, 5];
const bar = [];
foo.forEach((item) => bar.push(item));
console.log(bar); // [ 1, 2, 3, 4, 5 ]

map

배열의 각 요소에 대해 콜백 함수를 실행하고 반환 값을 모아 새로운 배열로 만듭니다.

const foo = [1, 2, 3, 4, 5];
const bar = foo.map((item) => item * 5);
console.log(bar); // [ 5, 10, 15, 20, 25 ]

filter

배열의 각 요소에 대해 콜백 함수를 실행하고 반환 값이 true인 값만 모아 새로운 배열로 만듭니다.

const foo = [1, 2, 3, 4, 5];
const bar = foo.filter((item) => item % 2 === 0);
console.log(bar); // [ 2, 4 ]

reduce

배열의 각 요소에 대해 누적 합계를 냅니다.

const foo = [1, 2, 3, 4, 5];
const bar = foo.reduce((a, b) => a + b);
console.log(bar); // 15

번외: 유사 배열 객체(array-like objects)?

배열을 제외한 자바스크립트의 객체에는 기본적으로 length 프로퍼티가 없습니다. 그런데 어떠한 방법으로든 객체에 length 프로퍼티가 추가되면 해당 객체는 유사 배열 객체로 기능하게 됩니다.

유사 배열 객체는 배열과 구조가 유사하나 map, forEach와 같은 배열 표준 메소드를 갖고 있지 않습니다.

대표적인 유사 배열 객체로는 Function.arguments가 있습니다.

✍️ 마치며

자바스크립트의 배열은 쓰는 방법만 안다면 매우 강력합니다. 특히 불변성을 유지하면서 배열을 수정하는 방법은 여러 곳에서 폭넓게 사용되니 다른 건 몰라도 불변성이 유지되는 map, filter, reduce, forEach 등의 메소드는 반복 숙달하는 것을 추천드립니다.

다음 포스트에서는 자바스크립트의 핵심이라고 할 수 있는 함수에 대해 다루겠습니다.

읽어 주셔서 감사합니다.

참고문헌

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array

profile
사진찍는 주니어 프론트엔드 개발자

0개의 댓글