27.1 배열이란?
- 배열의 길이를 나타내는 length 프로퍼티
- 배열을 생성하는 4가지 방법
- 배열 리터럴
- Array 생성자 함수
- Array.of
- Array.from
- Array.prototype은 배열을 위한 빌트인 메서드 제공
- 객체 vs. 배열
- 객체; 값의 순서 X, length 프로퍼티 X
- 배열; 값의 순서 O, length 프로퍼티 O
27.2 자바스크립트 배열은 배열이 아니다
- JS 배열은 배열의 요소가 연속적으로 이어져 있지 않은 Sparse array (희소 배열)
- JS 배열은 일반적인 배열의 동작을 흉내 낸 특수한 객체
- JS 배열은 인덱스를 나타내는 문자열을 프로퍼티 키로 가지며, length 프로퍼티 갖는 특수한 객체
(JS 배열의 요소는 사실 프로퍼티의 값)
- JS 배열은 해시 테이블로 구현된 객체임
27.3 length 프로퍼티와 희소 배열
- length 프로퍼티 값은 0 ~ 2^32 - 1 미만의 양의 정수
- 배열에서 사용할 수 있는 가장 작은 인덱스는 0, 가장 큰 인덱스는 2^32 - 2
- 현재 length 프로퍼티 값보다 큰 숫자 값 할당하게 되면, length 프로퍼티 값은 변경되지만
실제로 배열의 길이가 늘어나지는 않음 (empty로 표현됨)
- 값 없이 비어 있는 요소를 위해 메모리 공간 확보 X, 빈 요소 생성 X
- 희소 배열의 length 프로퍼티 값은 요소의 개수와 일치하지 않음
- 배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 최선임!
27.4 배열 생성
- 배열 리터럴
- 0개 이상의 요소를 쉼표로 구분하여 대괄호로 묶음
- Array 생성자 함수
- 전달된 인수의 개수에 따라 다르게 동작함
- 전달된 인수 개수가 0개이면 빈 배열 생성
- 전달된 인수 개수 1개이고 숫자인 경우, length 프로퍼티 값이 인수인 배열 생성
- 희소 배열, length 프로퍼티 값은 0이 아니지만 실제로 배열의 요소가 존재하지는 않음
- 전달된 인수 개수가 2개 이상 or 숫자가 아닌 경우 인수를 요소로 갖는 배열 생성
- new 연산자와 함께 호출하지 않고 일반 함수로서 호출해도 배열을 생성하는 생성자 함수로서 동작함
- Array 생성자 함수 내부에서 new.target을 확인하기 때문
- Array.of (ES6)
- 전달된 인수를 요소로 갖는 배열 생성
- Array.from (ES6)
- 유사 배열 객체 or 이터러블 객체를 인수로 전달받아 배열로 변환하여 반환
- 두 번째 인수로 전달한 콜백 함수를 통해 값을 만들면서 요소 채우기 가능
27.5 배열 요소의 참조
- 대괄호 표기법 사용
- 존재하지 않은 요소를 참조하면 undefined 반환 (희소 배열의 empty 부분 참조해도 동일)
27.6 배열 요소의 추가와 갱신
- 존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가됨 (length 프로퍼티 값은 자동 갱신)
- 이미 요소가 존재하는 요소에 값을 재할당하면 요소 값이 갱신됨
- 인덱스로 정수 (or 정수 형태의 문자열, 정수로 평가되는 표현식) 이외의 값을 사용하면 프로퍼티가 생성됨,
추가된 프로퍼티는 length 프로퍼티 값에 영향 주지 않음
27.7 배열 요소의 삭제
- delete 연산자 사용 가능 (length 프로퍼티에는 영향 주지 않음, 희소 배열이 됨)
- 희소 배열을 만들지 않으면서 배열의 특정 요소 완전히 삭제 위해 Array.prototype.splice() 메서드 사용
- length 프로퍼티도 자동 갱신됨
- Array.prototype.splice(삭제 시작할 인덱스, 삭제할 요소 개수)
27.8 배열 메서드
- Array.isArray
- Array 생성자 함수의 정적 메서드
- 전달된 인수가 배열이면 true, 배열이 아니면 false 반환
- Array.prototype.indexOf
- 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스 반환
- 두 번째 인수는 검색을 시작할 인덱스, 생략 시 처음부터 검색함
- 중복되는 여러 요소 있으면 첫 번째로 검색된 요소의 인덱스 반환
- 인수로 전달한 요소가 존재하지 않으면 -1 반환
- 배열에 특정 요소가 존재하는지 확인할 때 유용
- ES7 Array.prototype.includes 메서드 사용 시 가독성 더 좋음
- Array.prototype.push
- 인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가, 변경된 length 프로퍼티 값 반환
- 성능 면에서 좋지 않음
- legnth 프로퍼티 사용하여 배열의 마지막에 요소 직접 추가도 가능 (push 메서드보다 빠름)
- 원본 배열 직접 변경 (mutator method) <- side-effect 주의!
- ES6 스프레드 문법 사용하면 side-effect 없음!
- Array.prototype.pop
- 원본 배열에서 마지막 요소 제거하고 제거한 요소 반환
- 원본 배열 직접 변경
- pop 메서드와 push 메서드 사용하여 스택 쉽게 구현 가능
- Array.prototype.unshift
- 인수로 전달받은 모든 값을 원본 배열의 선두에 요소로 추가, 변경된 length 프로퍼티 값 반환
- 원본 배열 직접 변경
- ES6 스프레드 문법 사용 권장
- Array.prototype.shift
- 원본 배열에서 첫 번째 요소 제거하고 제거한 요소 반환
- 원본 배열 직접 변경
- shift 메서드와 push 메서드 사용하면 큐 쉽게 구현 가능
- Array.prototype.concat
- 인수로 전달된 값들(배열 또는 원시값)을 원본 배열의 마지막 요소로 추가한 새로운 배열 반환
- 인수로 전달받은 배열을 해체하여 새로운 배열의 요소로 추가
- 새로운 배열 생성하여 반환 (accessor method) <- 권장!
- push와 unshift 메서드는 concat 메서드로 대체 가능 (반환값을 변수에 할당해야 함)
- concat 메서드는 ES6 스프레드 문법으로 대체 가능 (권장)
- Array.prototype.splice
- 원본 배열의 중간에 요소 추가/제거할 때 사용
- 원본 배열 직접 변경
- 3개의 매개변수 (startIndex, deleteCount, InsertItems)
- 제거한 요소가 배열로 반환됨
- 두 번째 인수 생략하면 첫 번째 인수로 전달된 시작 인덱스부터 모든 요소 제거
- 배열에서 특정 요소 제거하려면 indexOf 메서드 같이 활용
- filter 메서드 사용하여 중복된 특정 요소 모두 제거 가능
- Array.prototype.slice
- 인수로 전달된 범위의 요소들을 복사하여 배열로 반환
- 원본 배열 보존됨
- 2개의 매개변수 (startIndex, endIndex)
- endIndex는 exclusive
- endIndex 생략 가능 (기본값은 length 프로퍼티 값)
- 인수 모두 생략하면 원본 배열의 복사본 생성하여 반환
- slice 메서드, 스프레드 문법, Object.assign 메서드 모두 얕은 복사 수행
(깊은 복사를 위해 Lodash 라이브러리의 cloneDeep 메서드 사용 권장)
- slice 메서드를 이용하면 유사 배열 객체를 배열로 변환 가능 (ES5)
- Array.from 메서드 사용하면 더 간단하게 유사 배열 객체 또는 이터러블 객체를 배열로 변환 가능
- 사실 ES6 스프레드 문법 사용하면 매우 간단함
- Array.prototype.join
- 원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 문자열(구분자)로 연결한 문자열 반환
- Array.prototype.reverse
- 원본 배열의 순서를 반대로 뒤집음
- 원본 배열이 변경됨
- Array.prototype.fill
- ES6, 인수로 전달받은 값을 배열의 처음부터 끝까지 요소로 채움
- 두 번째 인수로 요소 채우기 시작할 인덱스 설정 가능
- 배열 생성하면서 특정 값 요소로만 채우기 가능
- Array.from 메서드와 같이 활용하면 원하는 요소값으로 채우기 가능
- 원본 배열이 변경됨
- Array.prototype.includes
- ES7, 배열 내에 특정 요소 포함되어 있는지 확인하여 true/false 반환
- Array.prototype.flat
- ES10, 인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화
- 중첩 배열 모두 평탄화하기 위해서는 Infinity로 깊이 값 지정
27.9 배열 고차 함수
- Array.prototype.sort
- 배열의 요소를 정렬
- 원본 배열 직접 변경하며 정렬된 배열 반환 (기본은 오름차순, 문자열 기준)
- 숫자 요소 정렬 시에는 주의 필요!
- 배열의 요소를 일시적으로 문자열로 변환한 후 유니코드 코드 포인트 순서에 따라 정렬함
- 정렬 순서를 정의하는 비교 함수를 인수로 전달 필요 (양수, 음수, 0 반환)
- 비교 함수의 반환값이 0보다 작으면 비교 함수의 첫 번째 인수를 우선 정렬,
0이면 정렬 X, 0보다 크면 두 번째 인수를 우선하여 정렬
- 프로퍼티 값 비교할 때는 - 산술 연산이 아니라 비교 연산 이용
- Array.prototype.forEach
- for문 대체 가능한 고차 함수
- forEach 메서드는 forEach 메서드 호출한 원본 배열을 변경하지 않음
- 콜백 함수를 통해 원본 배열 변경은 가능
- forEach 메서드의 반환값은 항상 undefined
- forEach 메서드의 두 번째 인수로 forEach 메서드의 콜백 함수 내부에서 this로 사용할 객체 전달 가능
- forEach 메서드에 break, continue 문 사용 불가 (배열의 모든 요소를 빠짐없이 모두 순회해야 함)
- forEach 메서드는 희소 배열의 존재하지 않는 요소를 순회 대상에서 제외
- Array.prototype.map
- 자신을 호출한 배열의 모든 요소 순회하면서 인수로 전달받은 콜백 함수 반복 호출
- 콜백 함수의 반환값들로 구성된 새로운 배열 반환 (원본 배열 보존됨)
- map 메서드가 생성하여 반환하는 새로운 배열의 length 프로퍼티 값은
map 메서드 호출한 배열의 length 프로퍼티 값과 반드시 일치! (1:1 매핑됨)
- Array.prototype.filter
- 자신을 호출한 배열의 모든 요소 순회하면서 인수로 전달받은 콜백 함수 반복 호출
- 콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열 반환 (원본 배열 보존됨)
- filter 메서드가 생성하여 반환한 새로운 배열의 length 프로퍼티 값은
filter 메서드를 호출한 배열의 length 프로퍼티 값과 같거나 작음
- filter 메서드 사용하면 중복된 특정 요소 모두 제거됨
- 특정 요소 하나만 제거하려면 indexOf 메서드와 splice 메서드 이용
- Array.prototype.reduce
- 자신을 호출한 배열을 모든 요소를 순회하며 인수로 전달받은 콜백 함수 반복 호출
- 콜백 함수 반환값을 다음 순회할 때 콜백 함수의 첫 번째 인수로 전달하면서 콜백 함수 호출하여
하나의 결과값을 만들어 반환 (원본 배열 보존됨)
- reduce 메서드의 두 번째 매개변수로 초깃값 세팅하는 것이 안전함 (객체 프로퍼티 값 합산은 반드시 필요)
- 평균
- 최대값
- Math.max(...arr)이 더 직관적
- 요소 중복 횟수
- 중첩 배열 평탄화
- flat 메서드 사용하는 것이 더 직관적
- 중복 요소 제거
- filter 메서드 사용하는 것이 더 직관적
- Set 자료구조와 스프레드 활용하는 것 권장
- Array.prototype.some
- 자신을 호출한 배열의 요소를 순회하면서 인수로 전달된 콜백 함수 호출
- 콜백 함수의 반환값이 단 한 번이라도 참이면 true, 모두 거짓이면 false 반환
- 빈 배열은 언제나 false 반환
- Array.prototype.every
- 자신을 호출한 배열의 요소 순회하면서 인수로 전달된 콜백 함수 호출
- 콜백 함수의 반환값이 모두 참이면 true, 단 한 번이라도 거짓이면 false 반환
- 빈 배열은 언제나 true 반환
- Array.prototype.find
- ES6, 자신을 호출한 배열의 요소 순회하면서 인수로 전달된 콜백함수 호출하여
반환값이 true인 첫 번째 요소 반환
- Array.prototype.findIndex
- ES6, 자신을 호출한 배열의 요소 순회하면서 인수로 전달된 콜백 함수를 호출하여
반환값이 true인 첫 번째 요소의 인덱스 반환
- Array.prototype.flatMap
- ES10, map 메서드를 통해 생성된 새로운 배열을 평탄화시킴 (평탄화 깊이 1단계만 가능)
- map 메서드와 flat 메서드 순차적 실행 효과
- 평탄화 깊이 지정 필요 시에는 map 메서드와 flat 메서드 각각 호출
'Books > 모던 JS Deep Dive ✔️' 카테고리의 다른 글
[모던 JS Deep Dive] 29장 - Math (0) | 2022.01.15 |
---|---|
[모던 JS Deep Dive] 28장 - Number (0) | 2022.01.15 |
[모던 JS Deep Dive] 26장 - ES6 함수의 추가 기능 (0) | 2022.01.11 |
[모던 JS Deep Dive] 25장 - 클래스 (0) | 2022.01.10 |
[모던 JS Deep Dive] 24장 - 클로저 (0) | 2022.01.06 |
댓글