배열이라는 문법은 대부분의 프로그래밍 언어에 존재하고, 당연히 자바스크립트에도 존재한다.
또한, 배열의 활용도는 매우 높고 중요하기 때문에 정확히 알아둘 필요성이 있다.
1. Iterable, 유사 배열 객체
배열을 알기 위해서는 Iterable과 유사 배열 객체를 먼저 알아봐야한다.
1_1. Iterable
Iterable이란 반복 가능한 객체로, for-of문을 사용할 수 있는 특징이 있다.
이러한 Iterable에는 대표적으로 배열, Map, Set..등이 존재한다.
1_2. 유사 배열 객체
유사 배열 객체란 배열과 비슷한 형태를 갖고있고, length 프로퍼티를 갖고있는 객체로, 아이템에 엑세스하기 위해 인덱스를 사용하는 객체이다.
이러한 유사 배열 객체에는 대표적으로 NodeList, String...등이 존재한다.
2. 배열 생성
조금 배열에 대해 공부해보면 배열 생성 방법은 바로 알 수 있다.
const arr = [1, 2, 3]
위와 같은 방법으로 거의 모든 배열을 생성한다.
하지만, 특수한 경우 다른 배열 생성 방법을 요구할때도 있다.
2_1. 생성자 함수 이용
자바스크립트를 순서대로 공부하다 보면 생성자가 정확히 아직 알 수 없지만, 이런 방법이 있구나 하고 넘어가면 된다.
const numbers = new Array(1, 2);
위와 같은 방법으로 배열을 생성하는 것인데, 자세히 살펴보면 요소 1과 2를 갖는 numbers라는 이름의 배열을 생성하는 것이다.
다만, 생성자 함수를 이용해서 배열을 생성할때 주의할 점이 존재하는데,
const numbers = new Array(5);
위의 방식대로 해석해보면 이것은 요소 5를 갖는 numbers 배열일것이라 생각하겠지만, 이는 잘못되었다.
이것은 길이가 5지만 요소는 가지고있지 않는 numbers라는 빈 배열이다.
즉, 생성자를 이용해 배열을 생성할때 단일 숫자를 넣으면 해당 숫자 크기의 빈배열이 생성된다
*참고: new 키워드는 생략가능
2_2. Array.of() 이용
코드부터 보면
const numbers2 = Array.of(1, 2); 이런식으로 작성하면되고,
이는 요소 1,2를 가지는 numbers2라는 배열을 생성한다는 뜻이다.
2_3. Array.from() 이용
이 방법은 조금 특이하다.
배열을 생성하는 것은 맞지만, 배열로 만든다가 좀 더 다가오는 표현일것이다.
왜냐하면 Array.from()은 ()안에 Iterable 이나 유사배열객체가 들어가야하고 이를 배열로 변환시켜준다
const list = document.querySelectorAll("li");
console.log(list);
// 결과 => NodeList가 반환됨
const arrayItemList = Array.from(list);
console.log(arrayItemList);
// 결과 => 배열이 반환됨
여기서 드는 의문은 굳이 왜 이터러블이나 유사배열객체를 배열로 바꿔줘야하냐이다.
=> 오직 배열에만 지원하는 메서드들이 존재하기때문...즉, Array.from()을 통해 배열 메서드를 이터러블등에도 사용가능
2_정리.
- 배열 생성 방법 3가지
- 생성자 함수 - new Array()
- Array.of()
- Array.from()
- 이 중 가장 중요한것은 Array.from()
- 이터러블, 유사배열 -> 배열로 변환하여 배열 메서드 사용가능
3. 배열 메서드
2번에서 오직 배열에서만 사용 가능한 메서드들이 존재한다 했는데, 이를 정리해보려 한다.
- push()
배열 마지막 요소로 추가할 수 있음
const dummy = ["messi", "pedri"];
dummy.push("dejong");
// 결과 => ["messi", "pedri", "dejong"]
- pop()
배열 마지막 요소를 배열에서 삭제하여 반환함
const dummy = ["messi", "pedri", "dejong"];
const dum = dummy.pop();
console.log(dummy)
// 결과 => ["messi", "pedri"]
console.log(dum)
// 결과 => dejong
- unshift()
배열 처음 요소로 추가할 수 있음
const dummy = ["messi", "pedri"];
dummy.unshift("xavi");
console.log(dummy)
// 결과 => ["xavi", "messi", "pedri"]
- shift()
배열 처음 요소를 삭제함
const dummy = ["messi", "pedri"];
dummy.shift("xavi");
console.log(dummy)
// 결과 => ["messi", "pedri"]
*참고
- (un)shift 원리
- unshift() -> 배열의 요소들을 오른쪽으로 한칸씩 이동시키고 맨앞에 새요소 추가
- shift() -> 배열의 요소들을 왼쪽으로 한칸씩 이동시키고, 따라서 맨앞요소 삭제됨
- unshifth(), shift()는 모든 배열 요소에 영향을 미친다, 따라서 push(), pop()보다 느리다
- splice()
배열 두 요소 사이에 값을 삽입해주는 메서드
구조는
dummy.splice(시작 인덱스(0부터시작), 인덱스에서 삭제하려는 항목의 수, 삭제된 값의 위치에 삽입될 요소를 추가)
// 기존 dummy 배열 = ['messi', 'gavi']
dummy.splice(0, 0, "asdf");
console.log(dummy);
// 결과 => ['asdf', 'messi', 'gavi']
dummy.splice(0, 2, "qwer");
console.log(dummy);
// 결과 => ['qwer', 'gavi']
dummy.splice(1, 2, "zxcv");
console.log(dummy);
// 결과 => ['qwer', 'zxcv']
dummy.splice(1, 0, "poiu");
console.log(dummy);
// 결과 => ['qwer', 'poiu', 'zxcv']
- splice()는 삭제한 요소를 반환함
- 시작 인덱스를 음수로 지정하면 배열 맨끝 요소로 가서 시작한다
- slice()
배열은 기본적으로 참조 타입이므로, 복사(새로운 배열에 기존 배열 할당)하여도 값 복사가 아닌, 주소 복사라 기존 배열이 변경된것이 복사 배열에도 반영된다
const dummy = [1, 2, 3];
const copyDummy = dummy;
dummy.push(4);
console.log("기존배열: " + dummy + ", " + "복사배열: " + copyDummy);
// 결과 => 기존배열: 1,2,3,4, 복사배열: 1,2,3,4
하지만, 경우에 따라 기존의 배열 값이 바뀌어도 복사 배열의 값은 변경되지 않는 것을 원할때도 있다…이때 slice()를 사용
const dummy2 = [1, 2, 3];
const copyDummy2 = dummy2.slice();
dummy2.push(4);
console.log("기존배열: " + dummy2 + ", " + "복사배열: " + copyDummy2);
// 결과 => 기존배열: 1,2,3,4, 복사배열: 1,2,3
=> 즉, 배열을 복사하는데 사용되는 메서드이며, 이때 기존배열의 주소를 참조하는 것이 아닌, 새로운 배열을 생성하여 복사 한다.
또한, slice()는 배열 범위 선택에도 유용하게 사용가능하다
const dummy3 = [1, 2, 3, 4, 5];
const copyDummy3 = dummy3.slice(1, 4);
console.log(copyDummy3);
// 결과 => [2, 3, 4]
- slice(시작인덱스, 끝인덱스) ⇒ 시작인덱스 ≤ ~ < 끝인덱스 사이에 요소들을 선택해줌
- 끝인덱스 요소는 포함 안되는것 주의!
- slice(시작인덱스) ⇒ 시작인덱스 ≤ ~ ≤ 끝인덱스 사이에 요소들을 선택해줌
- concat()
배열과 배열을 연결할 때 사용하는 메서드
const dummy4 = [1, 2, 3];
const testDummy = [10, 11, 12];
const copyDummy4 = dummy4.concat(testDummy);
console.log(copyDummy4);
// 결과 => [1, 2, 3, 10, 11, 12]
dummy4.push(4);
console.log("기존배열: " + dummy4 + ", " + "복사배열: " + copyDummy4);
// 결과 => 기존배열: 1,2,3,4, 복사배열: 1,2,3,10,11,12
slice()와 마찬가지로 아예 새롭게 배열을 생성하여 복사하는 것이기 때문에 기존 배열 변경에 영향을 받지 않는다
*참고
push()에도 배열을 인자로 넣어 추가할 수 있지만, 이는 배열안에 배열이 삽입되는..즉, 중첩배열이 생성되는 것이고, concat()은 배열과 배열을 연결하여 새로운 하나의 배열을 반환한다는 차이점이 있다
- indexOf()
인자에 배열 요소값을 넣으면 해당 요소의 인덱스를 반환한다
const dummy5 = [1, 2, 3];
const dummyIndex = dummy5.indexOf(3);
console.log(dummyIndex);
// 결과 => 2
또한, 인자를 1개만 넣으면 전체배열에서 해당 요소를 탐색하지만, 두번째 인자에 탐색 시작 위치를 지정할 수 있다
const dummy6 = [1, 2, 3, 4, 5];
const dummyIndex2 = dummy6.indexOf(1, 4);
console.log(dummyIndex2);
// 결과 => -1
-> 찾으려는 요소가 시작 인덱스보다 앞에있어 -1을 반환한다(indexOf()는 탐색 실패시 -1을 반환함)
만약, 찾으려는 요소가 배열에 2개 이상있다면, 왼쪽에서부터 탐색했을때 가장 먼저 찾아지는 요소의 인덱스를 반환한다
const dummy7 = [1, 2, 3, 4, 5, 2, 3, 2, 2];
const dummyIndex3 = dummy7.indexOf(2);
console.log(dummyIndex3);
// 결과 => 1
indexOf()는 배열 왼쪽에서부터 탐색하는데, 만약 오른쪽부터 탐색하려면 lastIndexOf() 사용한다
const dummy8 = [1, 2, 3, 4, 5, 2, 3, 7, 8];
const dummyIndex4 = dummy8.lastIndexOf(2);
console.log(dummyIndex4);
// 결과 => 5
만약 배열의 요소가 참조값이면 indexOf()로 찾을 수 없다
const dummy9 = [{ age: 20 }, { age: 30 }];
const dummyIndex5 = dummy9.indexOf({ age: 20 });
console.log(dummyIndex5);
// 결과 => -1
-> 왜냐하면, 두 객체는 값이 똑같아도 다른 주소를 갖는 다른 참조값이기때문이다
- find()
indexOf()와 비슷한 기능을 하지만, 앞서 indexOf()의 한계점인, 참조값을 탐색 못하는 것을 보완해줄 수 있는 메서드이다.
const dummy10 = [{ age: 20 }, { age: 30 }, { name: "messi" }];
const dummyIndex6 = dummy10.find((dummy, idx, dummys) => {
return dummy.age === 30;
});
console.log(dummyIndex6);
// 결과 => { age: 30 }
-> find()는 주소를 복사하는 것이기때문에 가존 배열 변경과 서로의 변경에 영향을 받는다
dummyIndex6.age = 100;
console.log(dummy10);
//결과 => [{ age: 20 }, { age: 100 }, { name: "messi" }]
- include()
배열에 요소가 포함되어있는지를 확인할때 사용한다, 있다면 true를 없다면 false를 반환
이 글에서 배열에 대한 전반적인 것을 다뤄봤다.
정말 많은 배열 메서드들은 살펴봤지만,
이외에도 많은 메서드들이 존재하고 그 중 중요한 몇가지는 다른 글에서 다뤄볼려한다.
'OLD > Javascript' 카테고리의 다른 글
[Javascript] 자바스크립트 배열_03 (reduce(), 스프레드 연산자, 배열 구조 분해) (0) | 2023.02.20 |
---|---|
[Javascript] 자바스크립트 배열_02 (forEach(), map(), 정렬, 필터) (0) | 2023.02.18 |
[Javascript] DOM (DOM 쿼리, DOM Traversing) + live or non-live nodelist (0) | 2023.02.17 |
[Javascript] 속성 vs 프로퍼티 (0) | 2023.02.17 |
[Javascript] 자바스크립트에서의 함수(함수 표현식, 익명함수, Rest 연산자...) (0) | 2023.02.14 |