27.1 배열이란?
배열은 여러값을 순차적으로 나눈 자료구조이다.
// 배열접근
arr[0]
arr[1]
arr[2]
// 배열길이
arr.length // 3
// 배열은 객체타입
typeof arr // object
필자는 배열이라는 타입이 존재하지않아서 typeof 로 타입을 알아보면 객체타입이란걸 알수다니
이번에 알게된사실이다.
27.2 자바스크립트 배열은 배열이아니다.
배열은 인덱스를 통해 효율적으로 접근할수있다.
function searchText(array, target) {
const length = array.length;
for(let i = 0; i<length; i++ {
if(array[i] === target) return i;
}
return -1;
}
위의예제로 특정인덱스에 맞는 값을 찾으려면 차례대로 검색하기때문에 , 시간복잡도 O(n)이 커진다.
또한 추가하려면 배열 요소가 추가되면 그위치 뒷자리도 모두 이동시켜야하는 단점도있다.
하지만! 자바스크립트 배열은 위에처럼 말하는 일반적인 배열과다르다.
자바스크립트 배열은 연속적으로 이어져있지않을수도있고, 메모리공간도 다다를수있으며
일반적인 배열의 동작을 흉내낸 특수한 객체라는것이다.
필자는 자바스크립트 배열이 일반적인 배열과 다르게 생각해야된다는것을 새롭게 깨닳았다.
27.3 length 프로퍼티와 희소 배열
length 프로퍼티는 요소개수를 정수의 값으로 갖는다.
[].length // 0
[1,3.4].length // 3
const arr = [1,2,3,4,5];
arr.length = 3;
console.log(arr); // [1,2,3] 배열의 길이가 5 -> 3으로 줄어든다.
const arr = [1];
arr.length = 3;
console.log(arr.length); // 3
console.log(arr); // [1, empty * 2 ]. 배열길이를 늘려도 실제로 늘어나지않은다.
필자는 배열의 길이를 늘여도 배열이 길이가 늘어나지않고 실제로 값도 존재하지않는다는 사실을 알고간다.
배열길이를 늘였을때 null 값이들어갈줄알았었다.
const sparse = [, 2, 3, 4, , 2];
console.log(sparse); // [empty, 2, 3, 4, empty, 2]
이렇게 희소배열은 length랑 배열요소의 개수가 일치하지않는다.
배열을 생성할 경우에는 희소배열을 생성하지않도록 주의하자
필자는 배열의 길이가 정상적으로 요소랑 일치하지않을때 배열에 빈값이 들어가있는 희소배열형식이구나
라고 자바스크립트만의 배열특징때문에 이런현상이 발생하겠구나라고 인지할거같다.
- 희소배열 : 배열의 요소가 연속적으로 이어져있지않는 배열
27.4 배열생성
27.4.1 배열 리터럴
const arr = [1,2,3];
const arr2 = [];
const arr3 = [1, , 3]; // 희소배열
console.log(arr3[1]); // undefined
arr[1]이 undefined인 이유는 프로퍼티가 존재하지 않기때문이다.
27.4.2 Array 생성자 함수
Array 생성자 함수를 통해 배열을 생성할 수도잇다.
const arr = new Array(10); // 10자리생성, 희소배열
const arr = new Array(); // [] 과같다.
const arr = new Array(1,2,3); // [1,2,3]
const arr = new Array({}); // [{}]
27.4.3 Array.of
위의 Array 생성자랑다르게 인수가 1개여도 인수를 갖는 배열을 생성한다.
Array.of(1) // [1]
Array.of(1,2,3) // [1,2,3]
Array.of('string'); // ['string']
27.4.4 Array.from
이건 우선 넘어가보도록하겠다.
27.5 배열요소의참조
배열의 요소를 참조할때에는 대괄호 표기법을 사용한다.
const arr = [1,2]
console.log(arr[0]); //1
console.log(arr[1]); //2
console.log(arr[2]); //undefined
27.6 배열 요소의 추가와갱신
배열의 요소를 인덱스를 사용해 값을 할당하면 새로운 요소가 추가된다.
const arr = [0];
arr[1] = 1;
console.log(arr); // [0,1]
console.log(arr.length); // 2
// 큰인덱스로 요소를 추가하면 희소배열이된다.
arr[100] = 100;
console.log(arr); // [0, 1, empty * 98, 100);
console.log(arr.length); // 101
const arr = [];
// 배열 요소의 추가
arr[0] = 1;
arr['1'] = 2;
// 프로퍼티 추가
arr['foo'] = 3;
arr.bar = 4;
arr[1.1] = 5;
arr[-1] = 6;
console.log(arr); // [1, 2, foo:3, bar:4, '1.1':5, '-1':6]
// 프로퍼티는 length에 영향을 주지 않는다.
console.log(arr.length); // 2
필자는 이런 배열을 인덱스로 접근해서 추가할때 정수가 아니면 프로퍼티로 인식된다는 것을 알게되었다
그리고 length에 영향이 없다는 사실도 인식하게 되었다.
27.7 배열요소의 삭제
배열요소를 삭제하기 위해 희소배열을 만들지않으면서 삭제하려면 splice 메서드를 사용한다.
const arr = [1,2,3];
// Array.prototype.splice(삭제를 시작할 인덱스, 삭제할 인덱스수)
arr.splice(1,1);
console.log(arr); [1,3]
console.log(arr.length); // 2
27.8 배열 메서드
자바스크립트 배열은 다양한 메서드를 제공한다.
배열객체의 프로토타입인 Array.prototype는 프로토타입 메서드를 제공한다.
const arr = [1];
arr.push(2);
console.log(arr); // [1,2]
// concat 메서드는 원본배열을 변경하지않고 새로운 배열을 생성하여 반환한다.
const result = arr.concat(3);
console.log(arr); //[1,2]
console.log(result); // [1,2,3]
원본배열을 직접변경하는 메서드는 부수 효과가있으므로 주의해야한다.
따라서 가급적 원본배열을 직접 변경하지 않는 메서드를 사용하는 편이 좋다.
27.8.1 Array.isArray
Array.isArray는 Array 생성자 함수의 정적 메서드이다.
전달된 인수가 배열이면 true, 배열이 아니면 false를 반환한다.
Array.isArray([]); //true
Array.isArray([1,2]); // true
Array.isArray(new Array()); //true
Array.isArray({}); // false
Array.isArray(null); // false
Array.isArray(1); //false
27.8.2 Array.prototype.indexOf
indexOf 메서드는 원본배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환한다.
const arr = [1,2,2,3];
arr.indexOf(2); // 1
arr.indexOf(4); // -1 , 없으므로 -1을 리턴한다.
arr.indexOf(2, 2); // 2번째인수는 검색을 시작할 인덱스다.
indexOf메서드는 배열에 특정요소가 존재하는지 확인할때 유용하다.
대신, ES7에서 도입된 includes 메서드를 사용하면 가독성이 더좋다.
const foods = ['pizza', 'chicken', 'pasta'];
if(!foods.includes('orange')){
foods.push('orange');
}
console.log(foods); // ['pizza', 'chicken', 'pasta', 'orange'];
27.8.3 Array.prototype.push - 원본배열변경
push 메서드는 인수로 전달받은 모든값을 원본배열의 마지막요소를 추가하고 , 원본배열을 직접 변경한다.
const arr = 1, 2]'
let result = arr.push(3, 4);
consl.e.log(result); // 4
console.log(arr); [1,2,3,4];
하지만 성능 면에서 좋지않다. 또한 원본배열을 직접변경하기때문에
ES6의 스프레드 문법을 사용하는것이 좋다.
const arr = [1,2];
const newArr = [...arr, 3];
consle.log(newArr); // [1,2,3];
27.8.4 Array.prototype.pop - 원본배열변경
pop메서드는 원본 배열의 마지막요소를 제거하고 제거한 요소를 반환한다.
const arr = [1,2];
let result = arr.pop();
console.log(result); //2
console.log(arr); //[1]
27.8.5 Array.prototype.unshift - 원본배열변경
unsift메서드는 인수로 전달받은 모든값을 맨앞에 추가하고 변경된 length 프로퍼티를 반환한다.
const arr [1,2];
let result = arr.unshift(3,4);
console.log(result);
console.log(arr); // [3,4,1,2];
이것도 spread 연사자를 사용해서 앞에 추가하는 방법을 더추천한다.
const newArr = [3, ...arr];
27.8.6 Array.prototype.shift - 원본배열변경
shift 메서드는 원본배열에서 첫번째 요소를 제거한다.
const arr = [1,2];
let result = arr.shift();
console.log(result); // 1
console.log(arr); [2]
27.8.7 Array.prototype.concat - 원본배열변경 x, 새로운배열반환
concat 메서드는 인수로 전달된 값들을 원본배열의 마지막 요소로 추가한 새로운 배열을 반환한다.
const arr1 = [1,2];
const arr2 = [3,4];
let result = arr1.concat(arr2);
console.log(result); // [1,2,3,4]
result = arr1.concat(3);
console.log(result); // [1,2,3]
result = arr1.catcat(arr2, 5); // 배열 arr2와 숫자를 추가한 새로운 배열을 반환
console.log(result); // [1,2,3,4,5]
// 원본배열 변경 x
console.log(arr1); // [1,2]
catcat 메서드는 새로운 배열을 반환하기때문에 반드시 반환값을 변수에 저장해두어야한다.
let result = [1,2];
let result2 = [3,4];
result [...[1,2], ...[3,4]];
concat메서드보다 이렇게 스프레드 문법으로 간결하게 표현가능하니 더 사용하는 것을 권장한다.
필자는 concat과 push , unshift 메소드의 장단점을 알고나니 원본배열 변경 안정성, 등등 간결성때문에 스프레드 문법을 많이사용해서 배열을 추가 삭제하는 방법을 사용하는방법을 많이 사용하자라는 것을 느꼈다.
27.8.8 Array.prototype.splice -원본배열변경
원본 배열의 중간에 요소를 추가,제거하는경우 splice 메서드를 사용한다.
const arr = [1,2,3,4]
const result = arr.splice(1,2);
console.log(arr); // [1,4];
console.log(result); // [2,3] , 제거한 요소가 배열로반환
splice( 지정할시작인덱스 , 마지막인텍스);
27.8.9 Array.prototype.slice - -원본배열변경 x
slice 메서드는 인수로 전달된 범위의 요소를 복사하여 배열로 반환한다.
const arr = [1,2,3];
arr.slice(0,1); // [1]
arr.slice(1,2); // [2]
console.log(arr); // [1,2,3] 원본은 변경되지않는다.
//음수는 배열끝에서부터 요소를 복사하여 배열로 반환한다.
arr.slice(-1); // [3]
arr.slice(-2); // [2,3]
// 인수를 생략하면 원본배열 복사본을 생성하여 반환한다.
const copy = arr.slice();
console.log(copy); [1,2,3];
console.log(copy === arr); // false
얕은 복사를 통해 생성하므로 인술생략하여 복사본을 생성한다면 참조값이 서로다르다
- Array from은 우선넘어가도록하겠다.
27.8.10 Array.prototype.join
join 메서드는 원본 배열의 모든 요소를 문자열으로 변경후 인수로받은 구분자로 연결한 문자열을 반환한다.
const arr [1,2,3,4];
arr.join(); // '1,2,3,4';
arr.join(''); // '1234'
arr.join(':'); // '1:2:3:4'
27.8.11 Array.prototype.reverse
reverse 메서드는 원본배열의 순서를 반대로 뒤집는다. 이때 원본 배열이 변경된다.
const arr = [1,2,3];
const result = arr.reverse();
console.log(arr); // [3,2,1];
console.log(result); // [3,2,1]; 반환값을 변경된 배열이다.
27.8.12 Array.prototype.fill - 원본배열변경
ES6에 도입된 fill메서드는 인수로 전달받은 값을 배열의 처음부터 끝까지 요소로 채운다.
원본배열이 변경된다.
const arr = [1,2,3];
arr.fill(0);
console.log(arr); // [0,0,0]
arr.fill(0,1,2); // 값0을 시작인덱스 1부터 2까지 채운다
console.log(arr); // [1,0,0]; , 원본배열변경
27.8.13 Array.prototype.includes
includes메서드는 배열내에 특정요소가 포함되잇으면 true 아니면 false를 반환한다.
const arr = [1,2,3];
arr.includes(2); // true
arr.includes(100); // false
배열에서 특정요소를 포함되어있을때 사용하는것은 includes와 indexOf가있다
[NaN].indexOf(NaN) !== -1; // false
[NaN].includes(NaN)
27.8.14 Array.prototype.flat
flat 메서드는 인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화한다.
작성중...
'Book > 모던 자바스크립트 Deep Dive' 카테고리의 다른 글
14장 전역변수의 문제점 (1) | 2024.10.13 |
---|---|
12장 함수 (2) | 2024.10.08 |
11장 원시값과 객체의비교 (0) | 2024.10.02 |
10장 객체리터럴 (2) | 2024.10.02 |
8. 제어문 (1) | 2024.09.27 |