Skip to content

배열 (Array)

배열은 여러 개의 값을 하나의 변수에 순서대로 저장할 수 있는 자료구조이다. 자바스크립트에서 배열은 값의 순서가 중요한 데이터 집합을 효율적으로 관리하는 데 사용된다. 숫자, 문자열, 객체 등 다양한 타입의 값을 저장할 수 있으며, 각 요소는 숫자 인덱스를 통해 접근한다.

less
배열 (Array)
├── 배열 생성 방법
│   ├── 생성자 함수 방식 (Constructor Function)
│   └── 배열 리터럴 방식 (Array Literal)
└── 배열 요소 접근 및 관리
│   ├── 배열 요소 접근(출력)
│   ├── 배열 요소 수정
│   └── 배열 길이 확인 및 조정 (length)
└── 배열 메서드
    ├── 변형 메서드 (Mutator Methods)
    │   ├── push()       : 배열 끝에 요소 추가
    │   ├── unshift()    : 배열 앞에 요소 추가
    │   ├── pop()        : 배열 끝 요소 제거
    │   ├── shift()      : 배열 앞 요소 제거
    │   └── splice()     : 특정 위치 요소 추가/삭제
    ├── 순회 메서드
    │   ├── forEach()    : 각 요소를 반복 실행
    │   └── map()        : 요소 가공 후 새 배열 반환
    ├── 요소 탐색 메서드
    │   ├── at()         : 인덱스로 요소 반환 (음수 지원)
    │   ├── includes()   : 특정 값 포함 여부 확인
    │   ├── indexOf()    : 특정 값의 인덱스 반환
    │   ├── findIndex()  : 조건을 만족하는 첫 인덱스 반환
    │   └── find()       : 조건을 만족하는 첫 요소 반환
    ├── 추출 및 조작 메서드
    │   ├── filter()     : 조건 만족 요소만 새 배열로 반환
    │   ├── slice()      : 배열 일부를 복사해 새 배열 반환
    │   ├── concat()     : 배열을 이어붙여 새 배열 반환
    │   ├── join()       : 배열을 문자열로 결합
    │   ├── sort()       : 배열 정렬 (기본은 문자열 정렬)
    │   └── reduce()     : 누적하여 하나의 값으로 반환
    └── 정적 메서드 (Static Methods)
        └── Array.isArray() : 배열 여부를 boolean으로 반환

배열의 특징

  • 0부터 시작하는 인덱스: 배열의 요소는 인덱스를 기준으로 접근하며, 인덱스는 항상 0부터 시작한다.
  • 순서가 있는 데이터 구조: 배열은 각 요소가 삽입된 순서를 유지하며 저장되므로, 순차적 데이터 처리에 적합하다.
  • 동적 크기: 자바스크립트의 배열은 정해진 크기가 없으며, 요소를 추가하거나 제거하면 크기가 자동으로 조절된다.
  • 객체의 특수한 형태: 배열은 객체(Object)의 일종으로, 인덱스를 키(key)처럼 사용하지만 배열 전용 메서드와 속성이 제공되어, 데이터를 직관적으로 다룰 수 있다.

배열 생성 방법

less
배열 생성 방법
├── 생성자 함수 방식 (Constructor Function)
└── 배열 리터럴 방식 (Array Literal)

(1) 생성자 함수 방식 (Constructor Function)

new 키워드를 사용해 Array 생성자 함수를 호출하면 배열을 생성할 수 있다. 하지만 전달하는 인자의 개수에 따라 동작 방식이 달라지기 때문에, 직관성이 떨어져 잘 사용되진 않는다.

js
let arr = new Array(); // 빈 배열 생성

console.log(arr); // []
js
// 여러 개의 값을 넣으면, 각각 배열의 요소로 들어간다.
let array1 = new Array(1, 2, 3);
console.log(array1); // [1, 2, 3]

// 숫자 하나만 넣으면, 그 길이만큼 비어 있는 배열이 만들어진다.
let array2 = new Array(3);
console.log(array2); // [비어 있음 x 3]
  • 배열 생성자 new Array()는 여러 개의 값을 넣으면 각각 배열 요소가 된다. 숫자를 하나만 넣으면 그 숫자만큼 길이가 비어있는 배열이 만들어진다.

(2) 배열 리터럴 방식 (Array Literal)

[]대괄호를 사용하여 배열을 직접 선언 방식으로, 가장 많이 사용되는 배열 생성 방법이다.

js
let array1 = [];

console.log(array1); // []
js
let array1 = [1, 2, 3];
console.log(array1); // [1, 2, 3]

let array2 = [3];
console.log(array2); // [3]
  • 배열 리터럴을 사용하면 [] 안에 값을 나열하여 배열을 생성할 수 있다.
  • 배열의 요소들은 작성한 순서대로 저장되며, 인덱스를 통해 접근 가능하다.
  • 배열은 숫자, 문자열, 객체, 함수 등 어떤 자료형도 요소로 가질 수 있다.

배열 요소에 다양한 자료형 넣기

js
let arr = [
  { name: "바켸빈" },
  1,
  "array",
  function () {
    console.log("hello world!");
  },
  null,
  undefined,
];

console.log(arr);
// [{ name: "바켸빈" }, 1, "array", ƒ () { console.log("hello world!"); }, null, undefined]
  • 배열은 다양한 자료형의 데이터를 동시에 담을 수 있는 유연한 구조를 가지고 있다.

배열 요소 접근 및 관리

배열은 데이터가 위치한 순서인 인덱스를 통해 배열 요소에 접근한다. 배열의 인덱스는 0번부터 시작한다.

less
배열 요소 접근 및 관리
├── 배열 요소 접근(출력)
├── 배열 요소 수정
└── 배열 길이 확인 length: 배열의 전체 요소 개수 반환

(1) 배열 요소 접근(출력)

js
let arr = [1, "hello", null];

console.log(arr[0]); // 1
console.log(arr[1]); // "hello"
console.log(arr[2]); // null
  • 배열의 요소를 출력하기 위해서는 배열이름[인덱스 번호]를 작성하면 된다.

(2) 배열 요소 수정

배열은 전체를 새로운 값으로 재할당하거나, 인덱스를 통해 특정 요소를 직접 수정할 수 있다.

js
let color = ["black", "white", "brown"];

// 새로운 배열 재할당
color = ["black", "blue", "brown"];
// 배열의 3번째 요소 수정
color[2] = "yellow";

console.log(color); // ['black', 'blue', 'yellow']

const로 선언된 배열의 요소 변경

js
const color = ["black", "white", "brown"];

// 배열 자체를 재할당하려고 하면 에러 발생: TypeError
color = ["black", "blue", "brown"];

// 배열 내부 요소는 수정 가능
color[2] = "yellow";

console.log(color); // ['black', 'white', 'yellow']
  • 자바스크립트에서 배열은 객체의 일종으로(참조 타입)이기 때문에, const로 선언된 배열이라도 내부의 요소는 자유롭게 수정할 수 있다. 이는 배열 전체가 아닌, 배열이 가리키는 참조값(메모리 주소)은 그대로 유지되고, 그 내부 데이터만 바뀌기 때문이다.
  • const로 선언된 배열은 재할당이 불가능하다. 따라서 color = ["black", "blue", "brown"]과 같은 재할당은 에러가 발생한다.

(3) 배열 길이 확인 및 조정 (length)

배열의 요소 개수를 확인할 때는 length 프로퍼티를 사용한다. 배열의 길이는 요소의 개수를 기준으로 자동으로 계산되며, 인덱스의 최대값보다 1 큰 값이 된다.

js
const fruits = ["apple", "banana", "cherry", "date"];

console.log(fruits.length); // 4
  • length는 배열의 마지막 인덱스 + 1 값과 동일하다.
js
const fruits = ["apple", "banana", "cherry", "date"];
fruits.pop();

console.log(fruits); // ["apple", "banana", "cherry"]
console.log(fruits.length); // 3
  • pop() 메서드는 배열의 마지막 요소 "date"를 제거한다. 이로 인해 배열의 크기는 4에서 3으로 줄어든다.
  • length 프로퍼티는 자동으로 갱신되어, 변경된 배열의 길이인 3을 반환한다.
js
const empty = [];
console.log(empty.length); // 0
  • 빈 배열의 경우 length는 0이다.

length 프로퍼티를 이용한 배열 크기 조정

length 프로퍼티는 읽기 전용이 아니기 때문에 직접 값을 변경하면 배열의 길이를 인위적으로 조정할 수 있다. 이를 활용하면 배열을 잘라내거나 비우는 등의 작업도 가능하다.

length는 읽기 전용이 아니다 무슨 뜻일까?

자바스크립트에서 어떤 프로퍼티가 "읽기 전용(read-only)"이 아니다라는 말은, 그 값을 개발자가 직접 바꿀 수 있다는 뜻이다.


읽기 전용이 아닌 경우 (변경 가능)
js
let arr = [1, 2, 3];
arr.length = 1; // 길이를 줄임

console.log(arr); // [1]
  • arr.length = 1은 배열의 길이를 강제로 줄인 것으로, 실제로 배열이 잘려 나간다.
  • 즉, length는 단순히 정보를 제공하는 프로퍼티가 아니라, 배열 구조를 제어하는 수단이기도 하다.

읽기 전용인 경우 (변경 불가능)
js
const PI = 3.14;
PI = 3.14159; // TypeError: Assignment to constant variable.
  • const로 선언된 값은 변경할 수 없기 때문에 에러가 발생한다. 이런 값이 진짜 읽기 전용이다.

배열 길이 줄이기

배열의 length 값을 현재보다 작게 설정하면, 해당 길이 이후의 요소는 모두 삭제된다.

js
const fruits = ["apple", "banana", "cherry", "date"];
fruits.length = 2;

console.log(fruits); // ["apple", "banana"]
  • 인덱스 2 이상의 요소 "cherry", "date"는 잘려 나간다.

배열 비우기

배열을 비우는 가장 간단한 방법 중 하나는 length를 0으로 설정하는 것이다.

js
let arr = [1, 2, 3, 4, 5];
arr.length = 0;

console.log(arr); // []

배열 길이 늘리기

length를 현재보다 크게 설정하면, 비어 있는 요소(undefined) 가 뒤에 추가된다.

js
let arr = [1, 2];
arr.length = 5;

console.log(arr); // [1, 2, 비어 있음 x 3]
  • 하지만 이렇게 늘어난 공간은 실제 값이 없는 "비어 있는 슬롯" 으로, 반복문 등에서는 건너뛰는 경우도 있으니 주의가 필요하다.



배열 메서드 (Array Methods)

배열 메서드란 자바스크립트에서 배열 객체에 기본적으로 내장되어 있는 함수들을 의미한다. 배열에 직접 호출할 수 있는 메서드 형태로 제공된다.

less
배열 메서드
├── 변형 메서드 (Mutator Methods)
│   ├── push()       : 배열 끝에 요소 추가
│   ├── unshift()    : 배열 앞에 요소 추가
│   ├── pop()        : 배열 끝 요소 제거
│   ├── shift()      : 배열 앞 요소 제거
│   └── splice()     : 특정 위치 요소 추가/삭제
├── 순회 메서드
│   ├── forEach()    : 각 요소를 반복 실행
│   └── map()        : 요소 가공 후 새 배열 반환
├── 요소 탐색 메서드
│   ├── at()         : 인덱스로 요소 반환 (음수 지원)
│   ├── includes()   : 특정 값 포함 여부 확인
│   ├── indexOf()    : 특정 값의 인덱스 반환
│   ├── findIndex()  : 조건을 만족하는 첫 인덱스 반환
│   └── find()       : 조건을 만족하는 첫 요소 반환
├── 추출 및 조작 메서드
│   ├── filter()     : 조건 만족 요소만 새 배열로 반환
│   ├── slice()      : 배열 일부를 복사해 새 배열 반환
│   ├── concat()     : 배열을 이어붙여 새 배열 반환
│   ├── join()       : 배열을 문자열로 결합
│   ├── sort()       : 배열 정렬 (기본은 문자열 정렬)
│   └── reduce()     : 누적하여 하나의 값으로 반환
└── 정적 메서드 (Static Methods)
    └── Array.isArray() : 배열 여부를 boolean으로 반환

배열 변형 메서드 (추가 / 삭제)

less
배열 변형 메서드 (Mutator Methods)
├── 추가
│   ├── push()       : 배열 끝에 요소 추가
│   └── unshift()    : 배열 앞에 요소 추가
└── 삭제
    ├── pop()        : 배열 끝 요소 제거
    ├── shift()      : 배열 앞 요소 제거
    └── splice()     : 특정 위치 요소 추가/삭제

push()

push()는 배열의 내장 메서드로, 전달한 값을 배열의 맨 뒤에 추가한다. 배열 이름 뒤에 .push()를 붙이고, 괄호 안에 추가할 값을 전달하면 된다.

js
let arr = [1, "hello", null];

arr.push(10);
console.log(arr); // [1, "hello", null, 10]
  • arr.push(10)은 숫자 10을 배열의 마지막에 추가한다. 배열의 길이도 함께 증가한다.

unshift()

unshift()는 배열의 내장 메서드로, 전달한 값을 배열의 맨 앞에 추가한다.

js
let arr = [1, "hello", null];

arr.unshift(5);
console.log(arr); // [5, 1, "hello", null]
  • arr.unshift(5)은 숫자 5를 배열의 첫 번째 요소로 추가한다. 기존 요소들은 한 칸씩 뒤로 밀리며, 배열의 길이도 함께 증가한다.

pop()

pop()은 배열의 마지막 요소를 제거하고, 제거된 값을 반환하는 배열 내장 메서드이다. 이 메서드는 원본 배열을 변경한다.

js
const arr = [1, "hello", null];
arr.pop();

console.log(arr); // [1, "hello"]
  • 마지막 요소 null이 제거되어, 배열은 [1, "hello"]가 된다.
js
const arr = [1, "hello", null];
const removed = arr.pop();

console.log(removed); // null
  • pop() 메서드는 삭제된 요소를 반환하므로, 이 값을 변수에 저장할 수 있다.

shift()

배열의 첫 번째 요소를 제거할 때는 shift()라는 배열 내장 메서드를 사용한다. 삭제된 요소는 반환되며, 원본 배열은 변경된다.

js
const arr = [1, "hello", null];
arr.shift();

console.log(arr); // ["hello", null]
  • shift()는 배열의 첫 번째 요소인 1을 제거하고, 나머지 요소들을 앞으로 이동시킨다. 제거된 값은 반환되며, 필요할 경우 변수에 저장할 수 있다.
js
const arr = [1, "hello", null];
const removed = arr.shift();

console.log(removed); // 1
console.log(arr); // ["hello", null]
  • shift() 메서드는 제거된 요소인 1을 반환하고, arr 배열은 첫 번째 요소가 제거된 상태로 변경된다.

splice()

splice()는 배열에서 요소를 삭제하거나, 새로운 요소를 추가하거나, 기존 요소를 교체할 수 있는 배열 내장 메서드다. 이 메서드는 원본 배열을 직접 변경하며, 삭제된 요소를 배열로 반환한다.

js
array.splice(start, deleteCount, item1, item2, ...)
  • splice는 startdeleteCount 두 개의 인수를 받는다.
  • start: 변경을 시작할 인덱스
  • deleteCount: 제거할 요소의 갯수 (0으로 작성 시 삭제는 하지 않고 추가할 요소들이 그 위치에 삽입된다.)
  • item1, item2, ...: 삭제한 자리에 추가할 요소들 (생략 시 삭제만 수행)

요소 삭제

js
const fruits = ["apple", "banana", "cherry", "date"];
fruits.splice(1, 3);

console.log(fruits); // ["apple"]
  • 인덱스 1부터 시작해 총 3개의 요소를 삭제한다.
  • splice(1, 3)은 배열의 두 번째 요소부터 시작해서 총 3개 요소를 삭제하며, 이때 시작 인덱스(1)에 위치한 "banana"도 삭제 대상에 포함된다.

삭제된 요소 반환

js
const fruits = ["apple", "banana", "cherry", "date"];
const removed = fruits.splice(1, 2);

console.log(removed); // ["banana", "cherry"]
console.log(fruits); // ["apple", "date"]
  • 삭제된 요소는 splice()의 반환값으로 받을 수 있으며, 배열로 제공된다.

요소 추가 및 교체

js
const fruits = ["apple", "banana", "cherry", "date"];
fruits.splice(1, 2, "pineapple", "strawberry");

console.log(fruits); // ["apple", "pineapple", "strawberry", "date"]
  • 인덱스 1부터 2개 삭제 후, 새 요소가 추가된다.

삭제 없이 요소 삽입

js
const fruits = ["apple", "banana", "cherry"];
fruits.splice(1, 0, "pineapple");

console.log(fruits); // ["apple", "pineapple", "banana", "cherry"]
  • splice(1, 0, "pineapple")는 인덱스 1에 "pineapple"을 삽입하고, 아무 요소도 삭제하지 않는다. "banana"와 "cherry"는 뒤로 밀리게 됩니다.

배열 순회 메서드

less
배열 순회 메서드
├── forEach()    : 각 요소를 반복 실행
└── map()        : 요소 가공 후 새 배열 반환

forEach()

forEach() 메서드는 배열의 각 요소에 대해 한 번씩 지정한 함수를 실행하는 배열 전용 반복 메서드이다. Array.prototype.forEach()에 정의된 메서드로, 배열.forEach() 형태로 사용된다.

js
array.forEach((element, index, array) => {
  // 반복 실행할 코드
});
  • forEach 메서드는 최대 3개의 매개변수를 콜백 함수에 전달할 수 있다.
  • 현재 요소의 값, 해당 요소의 인덱스, 현재 실행중인 원본 배열

첫 번째 매개변수: 현재 요소

js
// for문을 사용해서 배열 요소에 접근하는 방식
let arr = [1, 2, 3, 4, 5];

for (let i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}
js
// forEach 메서드를 사용해 배열 요소에 접근하는 방식
let arr = [1, 2, 3, 4, 5];

arr.forEach((item) => {
  console.log(item);
});
  • forEach는 for문을 더 간결하게 대체할 수 있다.
  • 내부적으로 0번 인덱스부터 마지막 인덱스까지 요소를 자동으로 순회하며, 지정된 콜백 함수를 실행한다.
  • forEach는 중간에 break, continue 같은 흐름 제어문을 사용할 수 없다. 반복을 중단하거나 건너뛰는 제어가 필요한 경우에는 for, for...of, some(), every() 등을 사용하는 것이 좋다.

두 번째 매개변수: 인덱스

js
let arr = [1, 2, 3, 4, 5];

arr.forEach((item, idx) => {
  console.log(`${idx}번째 요소는 ${item}입니다.`);
});

// 0번째 요소는 1입니다.
// 1번째 요소는 2입니다.
// 2번째 요소는 3입니다.
// 3번째 요소는 4입니다.
// 4번째 요소는 5입니다.
  • 콜백함수의 두 번째 매개변수는 배열 요소의 인덱스를 나타낸다.
  • idx 인덱스 매개변수는 선택적인 매개변수(함수가 받을 수는 있지만, 반드시 전달하지 않아도 되는 매개변수)이다. 요소의 위치를 함께 출력하고 싶을 때 유용하다.

세 번째 매개변수: 원본 배열

js
let arr = [1, 2, 3, 4, 5];

arr.forEach((item, idx, array) => {
  console.log(`${idx}번째 요소는 ${item}입니다.`);
  console.log(array);
});

// 0번째 요소는 1입니다.
// [1, 2, 3, 4, 5]
// 1번째 요소는 2입니다.
// [1, 2, 3, 4, 5]
// 2번째 요소는 3입니다.
// [1, 2, 3, 4, 5]
// 3번째 요소는 4입니다.
// [1, 2, 3, 4, 5]
// 4번째 요소는 5입니다.
// [1, 2, 3, 4, 5]
  • 콜백함수의 세 번째 매개변수는 배열 요소의 수만큼 동일한 배열을 출력하는 매개변수이다. 모든 반복마다 동일한 배열을 반환한다.

map()

map()은 배열의 각 요소를 변형한 결과를 새로운 배열에 담아 반환하는 메서드이다. 기존 배열은 변경되지 않으며, 반환된 배열에는 콜백 함수의 실행 결과가 저장된다. Array.prototype.map()에 정의된 메서드이며, 배열.map() 형태로 사용된다. 전달한 콜백 함수의 반환값들로 구성된 새로운 배열을 생성하는 것이 특징이다.

js
const newArray = originalArray.map((element, index, array) => {
  // 새로운 요소 반환
});
  • map 메서드는 최대 3개의 매개변수를 콜백 함수에 전달할 수 있다.
  • 현재 요소의 값, 현재 요소의 인덱스, 현재 실행중인 원본 배열

첫 번째 매개변수: 현재 요소

js
// for문을 사용한 배열 변형
let arr = [1, 2, 3, 4, 5];

let newArray = [];

for (let i = 0; i < arr.length; i++) {
  newArray.push(arr[i] * 10);
}

console.log(newArray); //[10, 20, 30, 40, 50]
js
let arr = [1, 2, 3, 4, 5];

let newArray = arr.map((element) => {
  return element * 10;
});

console.log(newArray); //[10, 20, 30, 40, 50]
  • map은 for문을 짧고 직관적인 코드로 구현할 수 있다.
  • map은 배열의 모든 요소를 일정한 방식으로 변환할 때 유용한 메서드이다. 원본 배열은 변경하지 않고, 새로운 배열을 반환한다.

두 번째 매개변수: 인덱스

js
let arr = ["a", "b", "c"];

let result = arr.map((value, index) => {
  return `${index}: ${value}`;
});

console.log(result); // ["0: a", "1: b", "2: c"]

세 번째 매개변수: 원본 배열

js
let arr = [10, 20, 30];

let result = arr.map((value, index, array) => {
  console.log(array); // 반복마다 동일한 배열 출력
  return value / 10;
});

console.log(result);

// [10, 20, 30]
// [10, 20, 30]
// [10, 20, 30]
// [1, 2, 3]

요소 탐색 메서드

less
요소 탐색 메서드
├── at()         : 인덱스로 요소 반환 (음수 지원)
├── includes()   : 특정 값 포함 여부 확인
├── indexOf()    : 특정 값의 인덱스 반환
├── findIndex()  : 조건을 만족하는 첫 인덱스 반환
└── find()       : 조건을 만족하는 첫 요소 반환

at()

배열의 특정 위치에 있는 요소를 가져올 때 사용하는 메서드이다. 기존에는 대괄호 표기법 []을 사용했지만, at() 메서드를 활용하면 정수형 인덱스를 인자로 받아, 음수 인덱스도 사용할 수 있어 뒤에서부터 요소에 쉽게 접근할 수 있다. at 메서드는 배열뿐만 아니라 문자열에도 사용할 수 있다.

js
array.at(index);
  • array: 값을 가져올 대상 배열
  • index: 가져올 요소의 위치 (정수값, 음수 사용 가능)

배열.at()

js
// 기존 방식: 대괄호 표기법
let colors = ["green", "blue", "purple"];
console.log(colors[2]); // purple
js
// at()메서드 사용
let colors = ["green", "blue", "purple"];
console.log(colors.at(1)); // blue
console.log(colors.at(-1)); // purple
console.log(colors.at(-2)); // blue
  • at(index) 정수형 인덱스를 인자로 받아, 해당 위치의 요소를 반환한다.
  • 음수 인덱스를 사용하면 배열의 뒤에서부터 접근할 수 있어, colors.at(-1)colors[colors.length - 1]과 동일한 값을 반환한다.

문자열.at()

js
let str = "purple";
console.log(str.at(-1)); // e

includes()

includes 메서드는 매개변수로 받은 요소를 배열이 포함하고 있는지 확인하고, 결과를 boolean값으로 반환한다. 배열의 존재 여부를 직관적으로 검사할 수 있어 조건문과 함께 자주 사용된다. includes 메서드는 배열뿐만 아니라 문자열에도 사용할 수 있다.

js
array.includes(searchElement, fromIndex);
  • searchElement: 찾고 싶은 요소(필수)
  • fromIndex: 검색을 시작할 인덱스(선택, 기본값은 0)

배열.includes()

js
let colors = ["green", "blue", "purple"];
console.log(colors.includes("blue")); // true
console.log(colors.includes("black")); // false
  • 배열에 해당 값이 있으면 true, 없으면 false를 반환

두 번째 매개변수: fromIndex

js
let colors = ["green", "blue", "purple"];
console.log(colors.includes("green", 1)); // false
console.log(colors.includes("purple", 1)); // true
  • 두 번째 인수 fromIndex를 지정하면, 해당 인덱스부터 배열의 끝까지 검색을 시작한다.
  • 앞쪽 일부 요소를 의도적으로 건너뛰고 검색하고자 할 때 유용하다.

문자열.includes()

js
let str = "hello world";
console.log(str.includes("world")); // true
  • includes메서드는 문자열에서도 사용 가능하다.

indexOf()

indexOf 메서드는 배열에서 지정된 값이 처음 나타나는 인덱스를 반환하는 메서드이다. 만약 배열에 해당 요소가 없으면 -1을 반환한다. 기본 자료형(문자열, 숫자 등)은 비교할 수 있지만, 객체나 배열 같은 참조형은 내용이 같더라도 참조(메모리 주소)가 다르면 찾을 수 없다. 이는 내부적으로 ===엄격한 비교를 사용하기 때문이다.

js
array.indexOf(searchElement, fromIndex);
  • searchElement: 찾고 싶은 값 (필수)
  • fromIndex: 검색을 시작할 인덱스 (선택, 기본값은 0)
  • 반환값: 요소가 존재하면 해당 인덱스, 존재하지 않으면 -1

indexOf()

js
let colors = ["green", "blue", "purple"];
console.log(colors.indexOf("purple")); // 2
console.log(colors.indexOf("black")); // -1
  • 배열에서 지정한 값이 처음으로 나타나는 위치(인덱스)를 반환하고, 해당 값이 없으면 -1을 반환한다.

두 번째 매개변수: fromIndex

js
let colors = ["green", "blue", "purple"];

console.log(colors.indexOf("blue", 1)); // 1
console.log(colors.indexOf("green", 1)); // -1
  • blue는 인덱스 1에 있으므로 그대로 반환하고, green은 인덱스 0에 있지만, 인덱스 1부터 검색했기 때문에 찾지 못해 -1을 반환한다.

주의할 점

js
let colors = [
  { id: 1, color: "green" },
  { id: 2, color: "blue" },
  { id: 3, color: "purple" },
];

console.log(colors.indexOf("purple", 1)); // -1

// 내용이 같아도 다른 참조이기 때문에 -1 반환
console.log(colors.indexOf({ id: 3, color: "purple" })); // -1
js
// console.log(colors.indexOf("purple", 1));
// 위 코드는 이런 비교가 일어난다. 따라서 -1을 반환한다.
{ id: 1, color: "green" } === "purple" // false
{ id: 2, color: "blue" } === "purple"  // false
{ id: 3, color: "purple" } === "purple" // false
  • "purple"은 문자열이고, 배열 안에는 문자열이 아니라 객체가 들어있다.
  • 객체의 속성 값을 기준으로 찾을 때는 findIndex()를 사용해야 한다.

findIndex()

findIndex 메서드는 배열의 모든 요소에 대해 순차적으로 콜백함수를 실행하며, 조건을 만족하는 첫 번째 요소의 인덱스를 반환한다. 만약 조건을 만족하는 요소가 없으면 -1을 반환한다.

js
array.findIndex((element, index, array) => {
  // 조건식
}, thisArg);
  • element: 현재 순회중인 요소
  • index: 현재 요소의 인덱스 (선택)
  • array: 현재 순회중인 원본 배열 (선택)
  • thisArg: 콜백 함수 내부에서 this로 사용할 값 (선택, 일반적으로 자주 쓰이지 않음)

findIndex()

js
let colors = [
  { id: 1, color: "green" },
  { id: 2, color: "blue" },
  { id: 3, color: "purple" },
];

let idx = colors.findIndex((element) => element.color === "purple");

console.log(idx); // 2
  • 배열 요소가 객체일 경우, 예를 들어 color가 "purple"인 객체가 배열의 몇 번째 요소인지 찾으려면, indexOf()가 아닌 findIndex() 메서드를 사용해야 한다. indexOf()는 객체의 참조값을 비교하기 때문에, 내용이 같더라도 다른 객체로 인식되어 인덱스를 찾지 못한다.

findIndex() 세 매개변수 활용 예시

js
let colors = [
  { id: 1, color: "green" },
  { id: 2, color: "blue" },
  { id: 3, color: "purple" },
];

colors.findIndex((element, index, array) =>
  console.log(`${index}번째 값은 id: ${element.id}, color: ${element.color} `)
);

colors.findIndex((element, idx, array) => console.log(array));

// 0번째 값은 id: 1, color: green
// 1번째 값은 id: 2, color: blue
// 2번째 값은 id: 3, color: purple
// [ { id: 1, color: "green" }, { id: 2, color: "blue" }, { id: 3, color: "purple" }]
// [ { id: 1, color: "green" }, { id: 2, color: "blue" }, { id: 3, color: "purple" }]
// [ { id: 1, color: "green" }, { id: 2, color: "blue" }, { id: 3, color: "purple" }]

화살표 함수의 반환 방식

js
// 화살표 함수 한 줄 표현식
(element) => element.color === "purple";

// 암시적 반환
// 중괄호 없이 조건식을 작성하면 return 키워드를 생략해도 값을 자동으로 반환함
colors.findIndex((el) => el.color === "purple");

// 명시적 반환
// 중괄호를 사용하면 return을 명시적으로 작성해야 함
colors.findIndex((el) => {
  return el.color === "purple";
});
  • 중괄호 없이 바로 조건식을 쓰는 방식으로 암시적 반환이라고 한다. 중괄호 없이 작성하면 return 키워드를 생략해도 자동으로 값이 반환된다.

find()

find() 메서드는 배열에서 조건을 만족하는 첫 번째 요소 그 자체를 반환하는 메서드이다. 조건을 만족하는 요소가 없으면 undefined를 반환한다. 보통 객체 배열에서 원하는 조건의 객체 하나를 추출할 때 많이 사용된다.

js
array.find((element, index, array) => {
  // 조건식
}, thisArg);
  • element: 현재 순회중인 요소
  • index: 현재 요소의 인덱스 (선택)
  • array: 현재 순회중인 원본 배열 (선택)
  • thisArg: 콜백 함수 내부에서 this로 사용할 값 (선택, 일반적으로 자주 쓰이지 않음)
js
let colors = [
  { id: 1, color: "green" },
  { id: 2, color: "blue" },
  { id: 3, color: "purple" },
];

let idx = colors.find((element) => element.color === "purple");

console.log(idx); // { id: 3, color: "purple" }

추출 및 조작 메서드

less
추출 및 조작 메서드
├── filter()     : 조건 만족 요소만 새 배열로 반환
├── slice()      : 배열 일부를 복사해 새 배열 반환
├── concat()     : 배열을 이어붙여 새 배열 반환
├── join()       : 배열을 문자열로 결합
├── sort()       : 배열 정렬 (기본은 문자열 정렬)
└── reduce()     : 누적하여 하나의 값으로 반환

filter()

filter() 메서드는 배열에서 조건을 만족하는 모든 요소들만 따로 추출하여 새로운 배열을 만들어 반환한다. 조건에 맞지 않으면 빈 배열이 반환되며, 원본 배열은 변경되지 않는다.

js
array.filter((element, index, array) => {
  // 조건식이 true인 요소만 새로운 배열에 포함됨
});
  • element: 현재 순회중인 요소
  • index: 현재 요소의 인덱스 (선택)
  • array: 현재 순회중인 원본 배열 (선택)
js
let colors = [
  { id: 1, color: "green" },
  { id: 2, color: "blue" },
  { id: 3, color: "purple" },
];

let filterArray = colors.filter((element, idx, array) => element.id > 1);

console.log(filterArray);

// [{ id: 2, color: "blue" }, { id: 3, color: "purple" }]

slice()

slice() 메서드는 배열의 일부 구간을 잘라서 새로운 배열을 반환하는 메서드이다. 원본 배열은 변경되지 않으며, 시작 인덱스부터 끝 인덱스 직전까지의 요소를 복사한다.

js
array.slice(beginIndex, endIndex);
  • beginIndex: 잘라내기 시작할 인덱스 (필수, 포함)
  • endIndex: 현재 요소의 인덱스 (선택, 미포함)
js
let colors = ["green", "blue", "purple", "black"];

console.log(colors.slice(1, 3)); // ['blue', 'purple']
console.log(colors.slice(2)); // ['purple', 'black']
console.log(colors.slice()); // ['green', 'blue', 'purple', 'black']
  • slice(2): 인덱스 2부터 인덱스 끝까지 잘라 반환한다.
  • slice(): 배열 전체를 복사(얕은 복사)
js
let colors = [
  { id: 1, color: "green" },
  { id: 2, color: "blue" },
  { id: 3, color: "purple" },
  { id: 4, color: "yellow" },
];

let sliceArray = colors.slice(1, 3);

console.log(sliceArray);
// [{ id: 2, color: "blue" }, { id: 3, color: "purple" }]
  • slice(1, 3)은 인덱스 1부터 시작하여 인덱스 3 직전까지의 요소를 잘라 새로운 배열로 반환한다. 원본 배열은 변경되지 않고 그대로 유지된다.
js
let colors = ["green", "blue", "purple", "black"];
console.log(colors.slice(-2)); // ['purple', 'black']
  • 음수 인덱스도 사용 가능하다. -2는 뒤에서 두 번째 요소부터 시작을 의미한다.

concat()

concat() 메서드는 두 개 이상의 배열을 하나로 합쳐 새로운 배열을 반환하는 메서드이다. 기존 배열은 변경되지 않으며, 불변성(immutability)을 유지한다.

js
const newArray = array1.concat(array2, array3, ...);
js
let array1 = ["green", "blue"];
let array2 = ["purple", "yellow"];

console.log(array1.concat(array2));

// ['green', 'blue', 'purple', 'yellow']
  • array1과 array2를 합쳐서 새로운 배열을 생성한다.
  • 원본 배열 array1, array2는 변경되지 않는다. (불변성 유지)
js
let arr = [1, 2];
console.log(arr.concat(3, [4, 5])); // [1, 2, 3, 4, 5]
  • concat()은 배열뿐 아니라 배열이 아닌 값도 연결할 수 있다.

join()

join() 메서드는 배열의 모든 요소를 하나의 문자열로 결합하는 메서드이다. 배열을 합치는 concat()과는 달리, join()은 문자열을 반환한다.

js
let array1 = ["green", "blue", "purple", "yellow"];

console.log(array1.join()); // green,blue,purple,yellow
// 매개변수를 넣지 않으면 쉼표가 기본적인 구분자로 출력

console.log(array1.join(" ")); // green blue purple yellow
// space를 매개변수로 넣으면 공백 문자열이 구분자로 출력
  • 구분자를 전달하지 않으면 기본값으로 쉼표(,)가 사용된다.
  • " "처럼 공백 문자열을 넣으면 각 요소 사이에 공백이 삽입된다.
  • 문자열로 이어주기 때문에 숫자나 텍스트 목록을 표현할 때 유용하게 사용된다.
js
let digits = [1, 2, 3, 4];
console.log(digits.join("-")); // "1-2-3-4"
  • 단순히 출력용 문자열을 만들 때 자주 활용된다.

sort()

sort() 메서드는 배열의 요소를 정렬하고, 정렬된 배열을 반환한다. 원본 배열 자체가 변경되므로 주의해야 한다.

js
let colors = ["green", "blue", "purple"];
colors.sort();

console.log(colors); // ['blue', 'green', 'purple']
  • sort() 메서드에 인자를 전달하지 않으면, 배열의 요소들을 문자열로 변환한 후 유니코드(문자 코드) 순서에 따라 오름차순으로 정렬한다. 즉, 사전 순 정렬과 유사하게 동작한다.
js
const compare = (a, b) => {
  if (a > b) return -1;
  else if (a < b) return 1;
  else return 0;
};

let colors = ["green", "blue", "purple"];
colors.sort(compare);

console.log(colors); // ['purple', 'green', 'blue']

// compare 함수의 a, b는 서로 비교할 두 요소
// return 값이 < 0이면 a가 앞에, b가 뒤에 정렬됨
// return 값이 > 0이면 b가 앞에, a가 뒤에 정렬됨
// return 값이 0이면 순서를 바꾸지 않음
  • sort() 메서드는 배열을 정렬할 때 요소 쌍 a, b를 반복적으로 비교하고, 비교 함수의 반환값에 따라 순서를 결정한다.
  • 위 예시는 문자열을 내림차순(큰 → 작은) 으로 정렬한 것이다.
js
let numbers = [1, 100, 25, 50, 120, 3];
numbers.sort();

console.log(numbers); // [1, 100, 120, 25, 3, 50]
  • 아무 인자 없이 호출하면, 배열 요소들을 문자열로 변환해서 유니코드(문자 코드) 순서로 정렬한다.
  • 이 경우 문자열의 유니코드(문자 코드) 순서에 따라 정렬되므로, 우리가 기대하는 숫자 크기 기준의 정렬이 되지 않는다.
  • 예를 들어, 100은 25보다 유니코드 기준에서 앞서기 때문에 100이 먼저 정렬된다.
js
// 오름차순 정렬 (작은 숫자 → 큰 숫자)
const compare = (a, b) => {
  return a - b;
};

let numbers = [1, 100, 25, 50, 120, 3];
numbers.sort(compare);
console.log(numbers); // [1, 3, 25, 50, 100, 120]
  • a - b가 0보다 작으면 a가 앞에 오도록 정렬된다.
js
// 내림차순 정렬 (큰 숫자 → 작은 숫자)
const compare = (a, b) => {
  return b - a;
};

let numbers = [1, 100, 25, 50, 120, 3];
numbers.sort(compare);
console.log(numbers); // [120, 100, 50, 25, 3, 1]
  • b - a는 b가 a보다 크면 음수가 되어 b가 앞에 오도록 정렬된다.

reduce()

reduce() 메서드는 배열의 각 요소를 순서대로 처리하여 하나의 결과값으로 누적하는 메서드이다. 원본 배열은 변경되지 않는다.

js
array.reduce(callback, initialValue);
js
// 콜백함수 형태
(accumulator, currentValue, currentIndex, array) => {
  // 실행할 로직
  return 누적값;
};
js
array.reduce((accumulator, currentValue, currentIndex, array) => {
  // 실행할 로직
  return 누적값;
}, initialValue);
  • callback: 각 요소마다 실행할 함수
    • accumulator: 이전 콜백의 반환값을 누적하는 값
    • currentValue: 현재 처리 중인 요소
    • currentIndex: 현재 요소의 인덱스(선택)
    • array: reduce가 호출된 배열 자체 (선택)
  • initialValue: 누적값의 초기값 (선택, 생략하면 첫 번째 요소가 초기값이 됨)
js
// forEach를 사용한 누적 계산
let numbers = [1, 100, 25, 50];
let sum = 0;

numbers.forEach((element) => {
  sum += element;
});

console.log(sum); // 176
js
// reduce를 사용한 누적 계산
let numbers = [1, 100, 25, 50];
let sum = numbers.reduce((acc, cur, idx) => {
  console.log(acc, cur, idx);
  return acc + cur;
}, 0);

console.log(sum); // 176

// 0 1 0
// 1 100 1
// 101 25 2
// 126 50 3
// 176
  • reduce는 누적값을 인자로 전달하며 하나의 결과로 축약한다. 초기값부터 마지막까지 처리 후 반환값을 리턴한다.
  • forEach: 외부 변수에 누적하는 방식, reduce: 반환값을 통해 누적 결과를 얻는 방식
js
// reduce 초기값을 10으로 설정
let numbers = [1, 100, 25, 50];
let sum = numbers.reduce((acc, cur, idx) => {
  console.log(acc, cur, idx);
  return acc + cur;
}, 10);

console.log(sum); // 186

// 10 1 0
// 11 100 1
// 111 25 2
// 136 50 3
  • reduce(callback, initialValue)에서 initialValue를 지정하면 accumulator의 첫 값으로 사용되며, currentValue는 배열의 첫 번째 요소부터 시작한다.
  • initialValue를 생략하면 배열의 첫 번째 요소가 acc가 되고, currentValue는 두 번째 요소부터 시작한다.

정적 메서드

Array.isArray()

Array.isArray() 메서드는 주어진 값이 배열인지 아닌지를 판별하는 데 사용된다.

js
Array.isArray(value);
  • value: 배열인지 확인하고 싶은 값
js
let a = Array.isArray([1, 100, 50]);
let b = Array.isArray({ id: 3, color: "purple" });
let c = Array.isArray("string");
let d = Array.isArray(undefined);

console.log(a, b, c, d); // true false false false
  • 반환값: 배열이면 true, 배열이 아니면 false
js
console.log(typeof [1, 2, 3]); // object (배열도 객체로 나옴)
console.log(Array.isArray([1, 2, 3])); // true (정확히 배열로 인식)

console.log(typeof { a: 1 }); // object
console.log(Array.isArray({ a: 1 })); // false (객체는 배열이 아님)
  • typeof 연산자는 배열과 객체를 모두 'object'로 판단하기 때문에, 배열 여부를 확인할 때는 Array.isArray()를 사용하는 것이 가장 정확하다.