배열이란?
여러 개의 값을 순차적으로 나열한 자료구조
- 사용 빈도가 매우 높은 가장 기본적인 자료구조
const arr = ['apple', 'banana', 'orange'];
- 요소(element) : 배열이 가지고 있는 값
- 자바스크립트의 모든 값은 배열의 요소가 될 수 있다.
- 즉, 원시값은 물론 객체, 함수, 배열 등 자바스크립트에서 값으로 인정하는 모든 것은 배열의 요소가 될 수 있다.
- 배열의 요소는 배열에서 자신의 위치를 나타내는 0 이상의 정수인 인덱스(index)를 갖는다.
- 인덱스는 배열의 요소에 접근할 때 사용되며 대부분의 프로그래밍 언어에서 인덱스는 0부터 시작한다.
- 배열은 요소의 개수, 즉 배열의 길이를 나타내는 length 프로퍼티를 갖는다.
arr.length // -> 3
- 배열은 인덱스와 length 프로퍼티를 갖기 때문에 for문을 통해 순차적으로 요소에 접근할 수 있다.
// 배열의 순회
for (let i = 0; i < arr.length; i++) {
console.log(arr[i]); // 'apple' 'banana' 'orange'
}
자바스크립트에는 배열 타입이 존재하지 않고, 객체 타입이 존재한다.
- 자바스크립트의 배열은 객체지만 일반 객체와는 구별된 특징을 가진다.
구분 |
객체 |
배열 |
구조 |
프로퍼티 키와 프로퍼티 값 |
인덱스와 요소 |
값의 참조 |
프로퍼티 키 |
인덱스 |
값의 순서 |
X |
O |
length 프로퍼티 |
X |
O |
- 일반 객체와 배열을 구분하는 가장 명확한 차이는 값의 순서와 length 프로퍼티이다.
- 인덱스로 표현되는 값의 순서와 length 프로퍼티를 갖는 배열은 반복문을 통해 순차적으로 값에 접근하기 적합하다.
자바스크립트 배열은 배열이 아니다
✅밀집배열 (Dense Array)
배열의 요소가 하나의 데이터 타입으로 통일되어 있으며 서로 연속적으로 인접해 있는 배열
- 자료구조에서 일반적으로 언급하는 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조
- 인덱스를 통해 단 한 번의 연산으로 임의의 요소에 접근할 수 있다.
- 이 임의 접근(random access)은 시간복잡도 O(1)로 매우 효율적이며 고속으로 등장한다.
검색 대상 요소의 메모리 주소 = 배열의 시작 메모리 주소 + 인덱스 * 요소의 바이트 수
- 그러나 정렬되지 않은 배열에서 특정한 요소를 검색하는 경우 배열의 모든 요소를 처음부터 특정 요소를 발견할 때까지 차례대로 검색해야 한다.
- 이는 선형 검색(linear search)으로 시간복잡도가 O(n)이다.
- 또한, 배열에 요소를 삽입하거나 삭제하는 경우 배열의 요소를 연속적으로 유지하기 위해 요소를 이동시켜야 하는 단점이 있다.
✅희소배열 (Sparse Array)
배열의 요소가 연속적으로 이어져 있지 않는 배열
- 자바스크립트의 배열은 지금까지 살펴본 자료구조에서 말하는 일반적인 의미의 배열과 다르다.
- 배열의 요소를 위한 각각의 메모리 공간은 동일한 크기를 갖지 않아도 되며, 연속적으로 이어져 있지 않을 수도 있다.
- 자바스크립트의 배열은 일반적인 배열의 동작을 흉내낸 특수한 객체이다.
- 인덱스를 나타내는 문자열을 프로퍼티 키로 가지며, length 프로퍼티를 갖는다.
- 자바스크립트 배열의 요소는 사실 프로퍼티 값이다.
- 자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있다.
const arr = [
'string ,
10,
true,
null,
undefined,
NaN,
Infinity,
[ ],
{ },
function () {}
];
- 자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 요소에 잡근하는 경우 일반적인 배열보다 성능적인 면에서 느릴 수밖에 없는 구조적인 단점이 있다.
- 하지만 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대할 수 있다.
length 프로퍼티와 희소 배열
- length 프로퍼티는 요소의 개수, 즉 배열의 길이를 나타내는 0 이상의 정수를 값으로 갖는다.
- length 프로퍼티의 값은 빈 배열일 경우 0이며, 빈 배열이 아닐 경우 가장 큰 인덱스에 1을 더한 것과 같다.
- length 프로퍼티의 값은 0과 2^32 - 1(4,294,967,296 - 1) 미만의 양의 정수이다.
- 즉 , 배열은 요소를 최대 2^32 - 1(4,294,967,295) 개 가질 수 있다.
- 따라서 배열에서 사용할 수 있는 가장 작은 인덱스는 0이며, 가장 큰 인덱스는 2^32 - 2(4,294,967,294)이다.
- length 프로퍼티의 값은 배열에 요소를 추가하거나 삭제하면 자동 갱신된다.
- length 프로퍼티 값은 요소의 개수, 즉 배열의 길이를 바탕으로 결정되지만 임의의 숫자 값을 명시적으로 할당할 수도 있다.
- 현재 length 프로퍼티 값보다 작은 숫자 값을 할당하면 배열의 길이가 줄어든다.
- 현재 length 프로퍼티 값보다 큰 숫자 값을 할당하는 경우, length 프로퍼티 값은 변경되지만 실제로 배열의 길이가 늘어나지는 않는다.
- 값 없이 비어 있는 요소를 위해 메모리 공간을 확보하지 않으며 빈 요소를 생성하지도 않는다.
- 이처럼 배열의 요소가 연속적으로 위치하지 않고 일부가 비어 있는 배열을 희소 배열이라 한다.
- 일반적인 배열의 length는 배열 요소의 개수, 즉 배열의 길이와 언제나 일치하지만 희소 배열은 length 와 배열 요소의 개수가 일치하지 않는다
- 희소 배열의 length는 희소 배열의 실제 요소 개수보다 언제나 크다.
- 하지만 의도적으로 희소 배열을 만들어야 하는 상황은 발생하지 않기때문에 사용하지 않는 것이 좋다.
- 배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 최선이다.
배열 생성
✅배열 리터럴
- 가장 일반적이고 간편한 배열 생성 방식
- 배열 리터럴에 요소를 생략하면 희소 배열이 생성된다.
const arr = [1, , 3];
console.log(arr.length); // 3
console.log(arr); // [ 1, empty, 3 ]
console.log(arr[1]); // undefined
✅Array 생성자 함수
- Object 생성자 함수를 통해 객체를 생성할 수 있듯이 Array 생성자 함수를 통해 배열을 생성할 수도 있다.
- Array 생성자 함수는 전달된 인수의 개수에 따라 다르게 동작한다.
- 전달된 인수가 1개이고 숫자인 경우 length 프로퍼티 값이 인수인 배열을 생성한다.
- 이때 생성된 배열은 희소배열이고, length 프로퍼티 값은 0이 아니지만 실제로 배열의 요소는 존재하지 않는다.
- 배열은 요소를 최대 2^32 - 1(4,294,967,295개 가질 수 있기 때문에 Array 생성자 함수에 전달할 인수는 0 또는 2^32 - 1 (4,294,967,295) 이하인 양의 정수이어야 한다.
- 전달된 인수가 범위를 벗어나면 RangeError가 발생한다.
- 전달된 인수가 없는 경우 빈 배열을 생성한다. 즉, 배열 리터럴 [ ]과 같다.
- 전달된 인수가 2개 이상이거나 숫자가 아닌 경우, 인수를 요소로 갖는 배열을 생성한다.
- Array 생성자 함수는 일반 함수로서 호출해도 배열을 생성하는 생성자 함수로 동작한다.
- 이는 Array 생성자 함수 내부에서 new.target을 확인하기 때문이다.
✅Array.of
- Array.of는 Array 생성자 함수와 다르게 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
✅Array.from
- Array.from 메서드는 유사 배열 객체(array-like object) 또는 이터러블 객체(iterable object)를 인수로 전달받아 배열로 변환하여 반환한다.
- Array. from을 사용하면 두 번째 인수로 전달한 콜백 함수를 통해 값을 만들면서 요소를 채울 수 있다.
- Array. from 메서드는 두 번째 인수로 전달한 콜백 함수에 첫 번째 인수에 의해 생성된 배열의 요소값과 인덱스를 순차적으로 전달하면서 호출하고, 콜백 함수의 반환값으로 구성된 배열을 반환한다.
배열 요소의 참조
- 배열의 요소를 참조할 때에는 대괄호([]) 표기법을 사용한다.
- 대괄호 안에는 인덱스가 오고, 정수로 평가되는 표현식이라면 인덱스 대신 사용할 수 있다.
- 존재하지 않는 요소에 접근하면 undefined가 반환된다.
- 배열은 인덱스를 나타내는 문자열을 프로퍼티 키로 갖는 객체다.
- 따라서 존재하지 않는 프로퍼티 키 로 객체의 프로퍼티에 접근했을 때 undefined를 반환하는 것처럼 배열도 존재하지 않는 요소를 참조하면 undefined를 반환한다.
- 같은 이유로 희소 배열의 존재하지 않는 요소를 참조해도 undefined가 반환된다.
배열 요소의 추가와 갱신
- 객체에 프로퍼티를 동적으로 추가할 수 있는 것처럼 배열에도 요소를 동적으로 추가할 수 있다.
- 존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가되며 length 프로퍼티 값은 자동 갱신된다.
- 만약 현재 배열의 length 프로퍼티 값보다 큰 인덱스로 새로운 요소를 추가하면 희소 배열이 된다.
- 이때, 인덱스로 요소에 접근하여 명시적으로 값을 할당하지 않은 요소는 생성되지 않는다.
- 이미 요소가 존재하는 요소에 값을 재할당하면 요소값이 갱신된다.
- 인덱스는 요소의 위치를 나타내므로 반드시 0 이상의 정수 (또는 정수 형태의 문자열)를 사용해야한다.
- 만약 정수 이외의 값을 인덱스처럼 사용하면 요소가 아닌 프로퍼티가 생성된다.
- 이때 추가된 프로퍼티는 length 프로퍼티 값에 영향을 주지 않는다.
배열 요소의 삭제
- 배열은 객체이기 때문에 배열의 특정 요소를 삭제하기 위해 delete 연산자를 사용할 수 있다.
- delete 연산자는 객체의 프로퍼티를 삭제한다.
- 이때 배열은 희소 배열이 되며 length 프로퍼티 값은 변하지 않는다.
- 따라서 delete 연산자는 사용하지 않는 것이 좋다.
- 희소 배열을 만들지 않고 배열의 특정 요소를 완전히 삭제하려면 Array.prototype.splice 메서드를 사용한다.
배열 메서드
📍 Mutator Method
원본 배열을 직접 변경하는 메서드
📍 Accessor Method
원본 배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드
- 원본 배열: 배열 메서드를 호출한 배열. 즉, 배열 메서드의 구현체 내부에서 this가 가리키는 객체
- ES5부터 도입된 배열 메서드는 대부분 원본 배열을 직접 변경하지 않지만, 초창기 배열 메서드는 원본 배열을 직접 변경하는 경우가 많았다.
- 원본 배열을 직접 변경하는 메서드는 외부 상태를 직접 변경하는 부수 효과가 있으므로 사용할 때 주의해야 한다.
- 따라서 가급적 원본 배열을 직접 변경하지 않는 Accessor Method를 사용 하는 것이 좋다.
✅Array.isArray
Array 생성자 함수의 정적 메서드
- Array.isArray 메서드는 전달된 인수가 배열이면 true, 배열이 아니면 false를 반환한다.
✅Array.prototype.indexOf
- indexOf 메서드는 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환한다.
- 원본 배열에 인수로 전달한 요소와 중복되는 요소가 여러 개 있다면 첫 번째로 검색된 요소의 인덱스를 반환한다.
- 원본 배열에 인수로 전달한 요소가 존재하지 않으면 -1을 반환한다.
- indexOf 메서드는 배열에 특정 요소가 존재하는지 확인할 때 유용하다.
- indexOf 메서드 대신 ES7에서 도입된 Array.prototype.includes 메서드를 사용하면 가독정이 더 좋다.
✅Array.prototype.push
- push 메서드는 인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가하고 변경된 length 프로퍼티 값을 반환한다.
- push 메서드는 원본 배열을 직접 변경한다.
- push 메서드는 성능 면에서 좋지 않기 때문에 마지막 요소로 추가할 요소가 하나뿐이라면 length 프로퍼티를 사용하여 배열의 마지막에 요소를 직접 추가하는 것이 push 메서드보다 빠르다.
- Push 메서드는 원본 배열을 직접 변경하는 부수 효과가 있기 때문에 push 메서드보다 ES6의 스프레드 문법을 사용하면 함수 호출 없이 표현식으로 마지막에 요소를 추가할 수 있으며 부수 효과도 없다.
✅Array.prototype.pop
- pop 메서드는 원본 배열에서 마지막 요소를 제거하고 제거한 요소를 반환한다.
- 원본 배열이 빈 배열이면 undefined를 반환한다.
- pop 메서드는 원본 배열을 직접 변경한다.
- pop 메서드와 push 메서드를 사용하면 스택을 쉽게 구현할 수 있다.
📍스택(stack)
데이터를 마지막에 밀어 넣고, 마지막에 밀어 넣은 데이터를 먼저 꺼내는 후입 선출(LIFO - Last In First Out) 방식의 자료구조
- 스택은 언제나 가장 마지막에 밀어 넣은 최신 데이터를 먼저 취득한다.
- 스택에 데이터를 밀어 넣는 것을 push라 하고 스택에서 데이터를 꺼내는 것을 pop이라고 한다.
✅Array.prototype.unshift
- unshift 메서드는 인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가하고 변경된 length 프로퍼티 값을 반환한다. unshift 메서드는 원본 배열을 직접 변경한다.
- unshift 메서드는 원본 배열을 직접 변경하는 부수 효과가 있기 때문에 unshift 메서드보다 ES6의 스프레드 문법을 사용하면 함수 호출 없이 표현식으로 마지막에 요소를 추가할 수 있으며 부수 효과도 없다.
✅Array.prototype.shift
- shift 메서드는 원본 배열에서 첫 번째 요소를 제거하고 제거한 요소를 반환한다.
- 원본 배열이 빈 배열이면 undefined를 반환한다.
- shift 메서드는 원본 배열을 직접 변경한다.
- shift 메서드와 push 메서드를 사용하면 큐를 쉽게 구현할 수 있다.
📍큐(queue)
데이터를 마지막에 밀어 넣고, 처음 데이터, 즉 가장 먼저 밀어넣은 데이터를 먼저 꺼내는 선입 선출(FIFO - First In First Out) 방식의 자료구조
- 큐는 언제나 데이터를 밀어 넣은 순서대로 취득한다.
✅Array.prototype.concat
- concat 메서드는 인수로 전달된 값들(배열 또는 원시값)을 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환한다.
- 인수로 전달한 값이 배열인 경우 배열을 해체하여 새로운 배열의 요소로 추가한다.
- 원본 배열은 변경되지 않는다.
- push와 unshift 메서드는 concat 메서드로 대체할 수 있다.
- push와 unshift 메서드는 concat 메서드와 유사하게 동작하지만 다음과 같은 차이가 있다.
- push와 unshift 메사드는 원본 배열을 직접 변경하지만 concat 메사드는 원본 배열을 변경하지 않고 새로운 배열을 반환한다.
- 따라서 push와 unshift 메서드를 사용할 경우 원본 배열을 반드시 변수에 저장해 두어야 하며 concat 메서드를 사용할 경우 반환값을 반드시 변수에 할당받아야 한다.
- 인수로 전달받은 값이 배열인 경우 push와 unshift 메서드는 배열을 그대로 원본 배열의 마지막/첫 번째 요소로 추가하지만 concat 메사드는 안수로 전달받은 배열을 해체하여 새로운 배열의 마지막 요소로 추가한다.
- concat 메서드는 ES6의 스프레드 문법으로 대쳬할 수 있고, push/unshift 메서드와 concat 메서드를 사용하는 대신 스프레드 문법을 사용하는 것이 좋다.
✅Array.prototype.splice
- 원본 배열의 중간에 요소를 추가하거나 중간에 있는 요소를 제거하는 경우 splice 메서드를 사용한다.
- splice 메서드는 3개의 매개변수가 있으며 원본 배열을 직접 변경한다.
- start : 제거를 시작할 인덱스
- deleteCount : 시작 인덱스로부터 제거할 요소의 개수
- items : 요소를 제거한 후, 삭제한 인덱스로부터 추가할 데이터
- 배열에서 특정 요소를 제거하려면 indexOf 메서드를 통해 특정 요소의 인덱스를 취득한 후 splice 메서드를 사용한다.
✅Array.prototype.slice
- slice 메서드는 인수로 전달된 범위의 요소들을 복사하여 배열로 반환한다.
- 원본 배열은 변경되지 않으며, 이름이 유사한 splice 메서드는 원본 배열을 변경한다.
- slice 메서드는 두 개의 매개변수를 갖는다.
- start: 복사를 시작할 인덱스
- end: 복사를 종료할 인덱스
✅Array.prototype.join
- join 메서드는 원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 문자열, 즉 구분자(separator)로 연결한 문자열을 반환한다.
- 구분자는 생략 가능하며 기본구분자는 콤마(' , ')이다.
✅Array.prototype.reverse
- reverse 메서드는 원본 배열의 순서를 반대로 뒤집는다.
- 이때 원본 배열이 변경되며, 반환값은 변경된 배열이다.
✅Array.prototype.fill
- fill 메서드는 인수로 전달받은 값을 배열의 처음부터 끝까지 요소로 채우며, 이때 원본 배열이 변경된다.
- fill 메서드를 사용하면 배열을 생성하면서 특정 값으로 요소를 채울 수 있다.
- fill 메서드로 요소를 채울 경우 모든 요소를 하나의 값으로만 채울 수밖에 없다는 단점이 있다.
- 하지만 Array.from 메서드를 사용하면 두 번째 인수로 전달한 콜백 함수를 통해 요소값을 만들면서 배열을 채울 수 있다.
✅Array.prototype.includes
- includes 메서드는 배열 내에 특정 요소가 포함되어 있는지 확인하여 true 또는 false를 반환한다.
- 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환하는 indexOf 메서드를 통해서도 배열 내에 특정 요소가 포함되어 있는지 확인할 수 있다,
- 하지만 indexOf 메서드를 사용하면 반환값이 -1인지 확인해야 하고 배열에 NaN이 포함되어 있는지 확인할 수 없다는 문제가 있다.
✅Array.prototype.flat
- flat 메서드는 인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화한다.
- 중첩 배열을 평탄화할 깊이를 인수로 전달할 수 있다.
- 인수를 생략할 경우 기본값은 1이다.
- 인수로 Infinity 를 전달하면 중첩 배열 모두를 평탄화한다.
배열 고차 함수 (Higher-Order Function, HOF)
함수를 인수로 전달받거나 함수를 반환하는 함수
- 자바스크립트의 함수는 일급 객쳬이므로 함수를 값처럼 인수로 전달할 수 있으며 반환할 수 있다.
- 고차 함수는 외부 상태의 변경이나 가변 데이터를 피하고 불변성을 지향하는 함수형 프로그래밍에 기반을 둔다.
📍 함수형 프로그래밍
순수 함수와 보조 함수의 조합을 통해 로직 내에 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고 변수의 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임
- 함수형 프로그래밍은 순수 함수를 통해 부수 효과를 최대한 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 노력의 일환이다.
- 자바스크립트는 고차 함수를 다수 지원하며, 특히 배열은 매우 유용한 고차 함수를 제공한다.
✅Array.prototype.sort
- sort 메서드는 배열의 요소를 정렬한다.
- 원본 배열을 직접 변경하며 정렬된 배열을 반환한다.
- sort 메서드는 기본적으로 오름차순으로 요소를 정렬한다.
- 한글 문자열인 요소도 오름차순으로 정렬된다.
- 내림차순으로 요소를 정렬하려면 sort 메서드를 사용하여 오름차순으로 정렬한 후 reverse 메서드를 사용하여 요소의 순서를 뒤집는다.
- sort 메서드의 기본 정렬 순서는 유니코드 코드 포인트의 순서를 따른다.
- 배열의 요소가 숫자 타입이라 할지라도 배열의 요소를 일시적으로 문자열로 변환한 후 유니코드 코드 포인트의 순서를 기준으로 정렬한다.
- 따라서 숫자 요소를 정렬할 때는 sort 메서드에 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 한다.
✅Array.prototype.forEach
- forEach 메서드는 for문을 대체할 수 있는 고차 함수이다.
- forEach 메서드는 자신의 내부에서 반복문을 실행한다.
- 즉, 반복문을 추상화한 고차 함수로서 내부에서 반복문을 통해 자신을 호출한 배열을 순회하면서 수행해야 할 처리를 콜백 함수로 전달받아 반복 호출한다.
- forEach 메서드의 콜백 함수는 메서드를 호출한 배열의 요소값과 인덱스, forEach 메서드를 호출한 배열 자체, 즉 this를 순차적으로 전달받을 수 있다
- 즉 forEach 메서드를 호출한 배열의 요소값과 인덱스, forEach 메서드를 호출한 배열(this)을 순차적으로 전달한다.
- forEach 메서드의 반환값은 언제나 undefined다.
- forEach 메서드의 두 번째 인수로 forEach 메서드의 콜백 함수 내부에서 this로 사용할 객체를 전달할 수 있다.
- forEach 메서드는 for 문과는 달리 break, continue 문을 사용할 수 없다.
- 다시 말해 , 배열의 모든 요소를 빠짐없이 모두 순회하며 중간에 순회를 중단할 수 없다.
- 희소 배열의 경우 존재하지 않는 요소는 순회 대상에서 제외된다. (이는 map, filter, reduce에서도 마찬가지)
- forEach 메서드는 for문에 비해 성능이 좋지는 않지만 가독성은 더 좋다.
✅Array.prototype.map
- map 메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출하고 콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다.
- 이때 원본 배열은 변경되지 않는다.
📍forEach 메서드와 map 메서드의 공통점
- 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출한다.
- 콜백 함수를 호출할 때 3개의 인수를 순차적으로 전달한다.
- 메서드의 두 번째 인수로 메서드의 콜백 함수 내부에서 this로 사용할 객체를 전달할 수 있다.
📍forEach 메서드와 map 메서드의 차이점
- forEach 메서드는 언제나 undefined를 반환하고, map 메서드는 콜백 함수의 반환값들로 구성된 새로운 배열을 반환한다.
- 즉, forEach 메서드는 단순히 반복문을 대체하기 위한 고차 함수이고, map 메서드는 요소값을 다른 값으로 매핑한 새로운 배열을 생성하기 위한 고차 함수이다.
- map 메서드가 생성하여 반환하는 새로운 배열의 length 프로퍼티 값은 map 메서드를 호출한 배열의 length 프로퍼티 값과 반드시 일치한다.
- 즉 , map 메서드를 호출한 배열과 map 메서드가 생성하여 반환한 배열은 1:1 매핑한다.
✅Array.prototype.filter
- filter 메서드는 자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출하고 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환한다.
- 이때 원본 배열은 변경되지 않는다.
- filter 메서드가 생성하여 반환한 새로운 배열의 length 프로퍼티 값은 filter 메서드를 호출한 배열의 length 프로퍼티 값과 같거나 작다.
✅Array.prototype.reduce
- reduce 메서드는 자신을 호출한 배열을 모든 요소를 순회하며 인수로 전달받은 콜백 함수를 반복 호출하고 콜백 함수의 반환값을 다음 순회 시에 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수를 호출하여 하나의 결과값을 만들어 반환한다.
- 이때 원본 배열은 변경되지 않는다.
- reduce 메서드는 첫 번째 인수로 콜백 함수, 두 번째 인수로 초기값을 전달받는다.
- reduce 메서드의 콜백 함수에는 4개의 인수, 초기값 또는 콜백 함수의 이전 반환값, reduce 메서드를 호출한 배열의 요소값과 인덱스, reduce 메서드를 호출한 배열 자체, 즉 this가 전달된다.
- 이러한 과정을 반복하여 reduce 메서드는 하나의 결과값을 반환한다.
- reduce 메서드를 호출할 때는 언제나 초기값을 전달하는 것이 안전하다.
✅Array.prototype.some
- some 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출한다.
- 이때 some 메서드는 콜백 함수의 반환값이 단 한 번이라도 참이면 true, 모두 거짓이면 false를 반환한다.
- 즉, 배열의 요소 중에 콜백 함수를 통해 정의한 조건을 만족하는 요소가 1개 이상 존재하는지 확인하여 그 결과를 boolean 타입으로 반환한다.
- 단, some 메서드를 호출한 배열이 빈 배열인 경우 언제나 false를 반환한다.
- forEach, map, filter 메서드와 마찬가지로 some 메서드의 콜백 함수는 some 메서드를 호출한 요소값과 인덱스, some 메서드를 호출한 배열 자체, 즉 this를 순차적으로 전달받을 수 있다.
✅Array.prototype.find
- find 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫 번째 요소를 반환한다.
- 콜백 함수의 반환값이 true인 요소가 존재하지 않는다면 undefined를 반환한다.
- forEach, map, filter 메서드와 마찬가지로 find 메서드의 두 번째 인수로 find 메서드의 콜백 함수 내부에 서 this로 사용할 객체를 전달할 수 있다.
- 이보다 더 나은 방법은 화살표 함수를 사용하는 것이다.
✅Array.prototype.findIndex
- findlndex 메서드는 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수를 호출하여 반환값이 true인 첫 번째 요소의 인덱스를 반환한다.
- 콜백 함수의 반환값이 true인 요소가 존재하 지 않는다면 -1을 반환한다.
- forEach, map, filter 메서드와 마찬가지로 findlndex 메서드의 콜백 함수는 findlndex 메서드를 호출한 요소값과 인덱스, findlndex 메서드를 호출한 배열 자체, 즉 this를 순차적으로 전달받을 수 있다.
- forEach, map, filter 메서드와 마찬가지로 findIndex 메서드의 두 번째 인수로 findIndex 메서드의 콜백 함수 내부에 서 this로 사용할 객체를 전달할 수 있다.
- 이보다 더 나은 방법은 화살표 함수를 사용하는 것이다.
✅Array.prototype.flatMap
- flatMap 메서드는 map 메서드를 통해 생성된 새로운 배열을 평탄화한다.
- 즉, map 메서드와 flat 메서드를 순차적으로 실행하는 효과가 있다.
- 단, flatMap 메서드는 flat 메서드처럼 인수를 전달하여 평탄화 깊이를 지정할 수 없고 1단계만 평탄화한다.
- map 메서드를 통해 생성된 중첩 배열의 평탄화 깊이를 지정해야 하면 flatMap 메서드를 사용하지 말고 map 메서드와 flat 메서드를 각각 호출한다.