배열메서드1. 요소 조작
// 6가지의 요소 조작 메서드
// 1. push
// 배열의 맨 뒤에 새로운 요소를 추가하는 메서드
let arr1 = [1, 2, 3];
const newLength = arr1.push(4, 5, 6, 7);
// 2. pop
// 배열의 맨 뒤에 있는 요소를 제거하고, 반환
let arr2 = [1, 2, 3];
const poppedItem = arr2.pop();
// 3. shift
// 배열의 맨 앞에 있는 요소를 제거, 반환
let arr3 = [1, 2, 3];
const shiftedItem = arr3.shift();
// 4. unshift
// 배열의 맨 앞에 새로운 요소를 추가하는 메서드
let arr4 = [1, 2, 3];
const newLength2 = arr4.unshift(0);
// 5. slice
// 마치 가위처럼, 배열의 특정 범위를 잘라내서 새로운 배열로 반환
let arr5 = [1, 2, 3, 4, 5];
let sliced = arr5.slice(2, 5);
let sliced2 = arr5.slice(2);
let sliced3 = arr5.slice(-3); ///3,4,5
// 6. concat
// 두 개의 서로 다른 배열을 이어 붙여서 새로운 배열을 반환
let arr6 = [1, 2];
let arr7 = [3, 4];
let concatedArr = arr6.concat(arr7);
배열에 요소를 추가하는 push와 unshift는 추가 후 배열의 길이를 반환한다. 또한 push와 pop는 단순히 끝 인덱스만 조작하면 되기 때문에 시간복잡도는 O(1)이다. 하지만 shift와 unshift는 맨 앞 인덱스뿐만 아니라 전체 인덱스를 조작해야 하기 때문에 O(n)의 시간복잡도를 가진다. 따라서 가능하면 push와 pop으로 해결하는 것이 좋다!
slice는 배열의 특정 범위를 잘라내서 새로운 배열을 만드는데,배열명.slice(시작 인덱스, 끝 인덱스 + 1) 로 끝 인덱스에 +1을 해주어야 함을 명심하자. 배열 끝까지 자를 거면 두 번째 인수는 생략 가능하다. ' - (자를 개수) ' 를 이용하면 뒤에서부터 자를 수도 있다.
여기서 잠깐! 배열 메서드를 배우는데 의문이 들었다.. 분명 객체에서 메소드는 값이 함수인 프로퍼티였는데? 배열에서도 메서드가 나온다니. 잠깐 혼란이 왔었다. 그렇다면 배열도 객체라고 생각한다면..? 말이 됐었다. 배열이라는 틀을 우리는 마구 찍어서 사용하니까 말이다.
지피티에게 물어보니 정확하다고 했다. 🎯 (은근 칭찬해주는 거 기분 좋음) 배열도 객체의 한 종류이고, pop과 push같은 메서드를 프로퍼티로 가지고 있는 거라고. 즉 배열 메서드는 배열 객체의 프로퍼티로 존재하는 함수라고 보면 된다!
p.s. 강의록 다시 한 번 봤는데 배웠었다. 바보

배열메서드2. 순회와 탐색
// 5가지 요소 순회 및 탐색 메서드
// 1. forEach
// 모든 요소를 순회하면서, 각각의 요소에 특정 요소를 수행시키는 메서드
let arr1 = [1, 2, 3];
arr1.forEach(function (item, idx, arr) {
console.log(idx, item * 2);
});
let doubledArr = [];
arr1.forEach((item) => {
doubledArr.push(item * 2);
});
// 2. includes
// 배열에 특정 요소가 있는지 확인하는 메서드
let arr2 = [1, 2, 3];
let isInclude = arr2.includes(3);
// 3. indexOf
// 특정 요소의 인덱스(위치)를 찾아서 반환하는 메서드
let arr3 = [1, 2, 3];
let index = arr3.indexOf(2);
///얕은 비교. 특정 객체값 찾아낼 수 X
let objectArr = [{ name: "박진주" }, { name: "홍길동" }];
console.log(objectArr.indexOf({ name: "박진주" })); // -1
console.log(objectArr.findIndex((item) => item.name === "박진주")); // 0
// 4. findIndex
// 모든 요소를 순회하면서, 콜백함수를 만족하는
// 특정 요소의 인덱스(위치)를 반환하는 메서드
let arr4 = [1, 2, 3];
const findIndex = arr4.findIndex((item) => item === 2);
// 5. find
// 모든 요소를 순회하면서 콜백함수를 만족하는 요소를 찾는데, 요소를 그대로 반환
let arr5 = [{ name: "박진주" }, { name: "홍길동" }];
const finded = arr5.find((item) => item.name === "박진주");
console.log(finded);
indexOf vs findIndex
특정 요소의 인덱스를 찾아야 할 때, 우리는 두 가지 메서드를 사용할 수 있다. 두 메서드의 차이점은 findIndex는 콜백함수를 만족(true 반환)하는 인덱스를 반환한다는 것이다. 두 함수 모두 특정 요소가 존재하지 않으면 -1을 반환한다.
그렇다면 언제 무슨 메서드를 사용하는 게 좋을까?
indexOf는 얕은 비교를 하기 때문에 객체타입의 값을 비교하지 못한다. 반면 findIndex함수는 객체의 특정 프로퍼티에 직접 접근하여 조건문으로 비교하기 때문에, 객체타입의 값을 비교할 수 있다.
- 원시 타입의 값을 찾을 때 => indexOf
- 객체 타입의 값을 찾을 때 => findIndex
배열메서드3. 배열 변형
// 5가지 배열 변형 메서드
// 1. filter
// 기존 배열에서 조건을 만족하는 요소들만 필터링하여 새로운 배열로 반환
let arr1 = [
{ name: "박진주", hobby: "요가" },
{ name: "이정환", hobby: "테니스" },
{ name: "홍길동", hobby: "요가" },
];
const yogaPeople = arr1.filter((item) => item.hobby === "요가");
// 2. map
// 배열의 모든 요소를 순회하면서, 각각 콜백함수를 실행하고 그 결과값들을 모아서 새로운 배열로 반환
let arr2 = [1, 2, 3];
const mapResult = arr2.map((item, idx, arr) => {
return item * 2;
});
let names = arr1.map((item) => item.name);
// 3. sort
// 배열을 사전순으로 정렬하는 메서드
let arr3 = [10, 3, 5];
arr3.sort((a, b) => {
if (a > b) {
// b가 a 앞에 와라
return 1; // -> b, a 배치
} else if (a < b) {
// a가 b 앞에 와라
return -1; // -> a, b 배치
} else {
// 두 값의 자리를 바꾸지 마라
return 0; // a, b 자리를 그대로 유지
}
});
// 4. toSorted (가장 최근에 추가된 최신 함수)
// 정렬된 새로운 배열을 반환하는 메서드
let arr5 = ["c", "a", "b"];
const sorted = arr5.toSorted();
// 5. join
// 배열의 모든 요소를 하나의 문자로 합쳐서 반환하는 메서드
let arr6 = ["hi", "im", "jinju"];
const joined = arr6.join(' ');
// 기본 구분자는 쉼표. 바꾸고 싶으면 인수 자리 변경
filter 메서드는 find 메서드와 비슷하다. 하지만 조건을 만족하는 요소를 직접 반환하는 find와 달리, filter 메서드는 조건을 만족하는 요소를 모아 배열로 반환한다.
map 메서드는 요소의 값을 변형하여 새로운 배열을 만들어 반환하는 메서드이다. 아주 자주 쓰이는 메서드라고 하니 기억해두자.
배열 메서드 map을 사용할 때 객체를 반환하려면 화살표 옆 중괄호를 소괄호로 감싸야 한다. 그렇지 않으면 객체가 아니라 블록으로 처리해버리기 때문이다.
sort 메서드는 "사전순(문자열 오름차순)으로" 배열하기 때문에 10이 3보다 앞으로 정렬된다. 숫자를 정렬하기 위해서는 sort 메서드의 인수에 콜백함수(여기선 비교 함수)를 넣어주어야 한다. 작성하지 않을 시 사전순으로 정렬된다. sort 메서드는 내부적으로 정렬 알고리즘이 실행된다. 그래서 우리가 양수, 0, 또는 음수 값을 리턴해주면 그것에 따라 정렬 알고리즘을 실행한다. a, b를 비교했을 때
- return 1 => b, a 순으로 정렬
- return 0 => 자리 바꾸지 않고 유지
- return -1 => a, b 순으로 정렬
그럼 return 0 과 -1 의 차이가 없지 않은가? 싶을 수 있다. 표면적으로 그렇지만, 0은 유지해도 상관없다는 뜻, -1은 a가 b보다 앞에 와야한다고 명시하는 미묘한 차이가 있다고 한다.
배열 메서드 너무 많아.. 머리 깨진다 🙀 그래도 웬만한 기능이 다 있으니 필요할 때 찾아서 쓰면 될 것 같다.
Date 객체와 날짜
// 1. Date 객체를 생성하는 방법
let date1 = new Date(); // 생성자
let date2 = new Date(1997, 1, 7, 10, 23, 23);
// 2. 타임 스탬프
// 특정 시간이 "1970.01.01 00시 00분 00초"로 부터 몇 ms가 지났는지를 의미하는 숫자값
let ts1 = date1.getTime();
let date4 = new Date(ts1);
// 3. 시간 요소들을 추출하는 방법
let year = date1.getFullYear();
let month = date1.getMonth() + 1; // 월: 0부터 시작
let date = date1.getDate();
let hour = date1.getHours();
let minute = date1.getMinutes();
let seconds = date1.getSeconds();
// 4. 시간 수정하기
date1.setFullYear(2023);
date1.setMonth(2); // 3월
date1.setDate(30);
date1.setHours(16);
date1.setMinutes(38);
date1.setSeconds(20);
// 5. 시간을 여러 포맷으로 출력하기
console.log(date1.toDateString());
console.log(date1.toLocaleString());
자바스크립트의 월은 인덱스처럼 0부터 시작한다. 즉 0은 1월, 1을 2월 이런 식으로... 따라서 월을 다룰 때는 항상 주의하자.
'프론트엔드 > 한 입 크기로 잘라먹는 리액트' 카테고리의 다른 글
| Node.js - 모듈 시스템, 라이브러리 (2) | 2025.01.20 |
|---|---|
| JavaScript - 동기와 비동기, 비동기 작업 처리하기(콜백함수, Promise, Async&Await) (1) | 2025.01.17 |
| JavaScript - 구조분해할당, Spread 연산자와 Rest 매개변수, 원시타입 VS 객체타입, 반복문으로 배열과 객체 순회하기 (1) | 2025.01.15 |
| JavaScript - 객체, 배열, Truthy와 Falsy, 단락 평가 (0) | 2025.01.13 |
| JavaScript - 반복문, 함수, 함수 표현식과 화살표 함수, 스코프 (0) | 2025.01.13 |