Javascript
자바스크립트 꼭 알아야하는 배열 메서드 총정리!!(메모리 공간 사용 여부까지)
JANNNNNN
2024. 9. 25. 22:49
JavaScript에서 배열 메서드는 메모리 사용 방식에 따라 원본 데이터를 수정하거나 새로운 데이터를 반환할 수 있는데요. 이 차이를 이해하면 코드 작성 시 데이터 무결성을 유지할 수 있고, 특히 협업에서 복잡한 로직을 구현할 때 오류를 줄이는 데 도움이 됩니다! 이제 각 메서드가 메모리를 어떻게 사용하는지, 현업에서 어떤 메서드가 자주 사용되는지, 그 이유를 함께 정리해볼게요 :)
📍배열 메서드와 메모리 관리
메모리 사용의 차이: 기존 배열 수정 vs. 새로운 배열 반환
- 기존 배열 수정: 메서드가 원본 배열을 직접 변경합니다. 데이터가 기존 메모리 공간에 그대로 덮어씌워지므로 추가 메모리 사용이 없습니다.
- 새로운 배열 반환: 메서드가 새로운 배열을 생성하여 반환합니다. 이때 원본 배열은 수정되지 않고, 새로운 메모리 공간에 저장됩니다.
⭐️중요: 메모리 사용 차이를 알아야 하는 이유
- 데이터 무결성: 원본 데이터를 보호하고, 불필요한 데이터 변경을 막아 예측 가능한 코드를 작성할 수 있습니다.
- 성능 최적화: 메모리를 효율적으로 사용하고, 필요한 경우에만 새로운 공간을 할당함으로써 성능을 유지할 수 있습니다.
- 디버깅 용이성: 원본 데이터가 변하지 않으면 디버깅 과정에서 데이터 흐름을 더 쉽게 추적할 수 있습니다
➡️기존 배열을 수정하는 메서드 (메모리 공간 사용 안 함)
1. push()와 pop()
- push(): 배열 끝에 요소 추가.
- pop(): 배열 끝에서 요소 제거.
let members = [ '1', '2', '3', '4'];
members.push('5'); // 5추가
console.log(memebrs); // [ '1', '2', '3', '4', '5' ]
members.pop(); // 마지막 요소 제거
console.log(members); // [ '1', '2', '3', '4' ]
⭐️중요 : push()와 pop()은 원본 배열을 수정합니다.
2. shift()와 unshift()
- shitf() : 배열 첫 요소 제거
- unshitf() : 배열 첫 부분에 요소 제거
members.shift(); // 첫 요소 제거
console.log(members); // [ '2', '3', '4' ]
members.unshift('new'); // 첫 부분에 'new' 추가
console.log(members); // [ 'new', '2', '3', '4' ]
⭐️중요 : shitf와 unshitf도 원본 배열을 수정합니다.
3. splice()
- splice(start, deleteCount): 배열에서 요소를 제거하거나 추가.
console.log(members.splice(0, 3)); // 첫 3개 요소 제거
⭐️중요 : spclie도 원본 배열을 수정합니다.
4. sort()와 reverse()
- sort(): 배열을 오름차순으로 정렬.
- reverse(): 배열을 내림차순으로 정렬
let num = [1, 9, 7, 0, 3];
num.sort((a, b) => a - b); // 오름차순
console.log(num); // [0, 1, 3, 7, 9]
num.reverse(); // 내림차순
console.log(num); // [9, 7, 3, 1, 0]
⭐️중요: 현업에서 잘 사용되지 않는 이유
- 원본 데이터 변경 위험: 실수로 원본 데이터를 변경하면 예기치 않은 오류가 발생할 수 있어 유지보수가 어려워집니다.
- 데이터 추적 어려움: 데이터를 예측하고 추적하는 데 혼란을 줄 수 있습니다.
➡️새로운 배열을 반환하는 메서드 (메모리 공간 사용)
1. concat()
- concat(): 두 배열을 합쳐서 새로운 배열 반환.
let numbers = ['0', '1', '2', '3'];
console.log(numbers.concat('new')); // [ '0', '1', '2', '3', 'new' ]
⭐️중요 : push와 로직 자체는 비슷하지만, concat는 기존의 값을 변경하지 않습니다.
2. slice()
- slice(start, end): 배열의 일부분을 추출하여 새로운 배열 반환.
console.log(numbers.slice(0, 3)); // [ '0', '1', '2' ]
⭐️중요 : splice와 로직 자체는 비슷하지만, slice는 기존의 값을 변경하지 않습니다.
3. map()
- 배열의 각 요소를 변환하여 새로운 배열 반환.
console.log(num.map((x) => `숫자들: ${x}`)); // ['숫자들: 9', ...]
4. filter()
- 조건에 맞는 요소들만 모아 새로운 배열 반환
let number = [1, 3, 4, 8];
console.log(number.filter((x) => x % 2 === 0)); // [4, 8]
5. find()와 findeIndex()
- find(): 첫 번째로 조건을 만족하는 요소 반환.
- findIndex(): 조건을 만족하는 첫 요소의 인덱스 반환.
let numbers = ['0', '1', '2', '3'];
console.log(number.find((x) => x % 2 === 0)); // 4
console.log(number.findIndex((x) => x % 2 === 0)); // 2
⭐️중요: filter와 find의 차이점은, filter은 조건에 맞는 요소들을 모아서 반환하고, find는 조건에 맞는 요소를 찾으면 처음 그 값을 반환합니다.
6. reduce()
- 배열의 모든 요소를 누적하여 하나의 값으로 줄임.
console.log(number.reduce((p, n) => p + n, 0)); // 16
⭐️중요 : reduce()는 누적 작업을 수행할 때 유용하며, 첫 번째 매개변수는 누적값, 두 번째는 현재 요소입니다.
📘 reduce() 사용법(자주 헷갈리므로..)
array.reduce((accumulator, currentValue, index, array) => {
// 로직
}, initialValue);
매개변수
- accumulator (누적기): 이전 콜백 함수의 반환값을 저장합니다. 초기값이 없을 때는 배열의 첫 번째 요소가 초기 누적기가 됩니다.
- currentValue (현재 값): 현재 배열 요소를 의미합니다.
- index (인덱스): 현재 요소의 인덱스 (선택 사항).
- array (배열): 호출한 배열 자체 (선택 사항).
- initialValue (초기값): 누적 계산을 시작할 때 사용할 초기값을 지정합니다. 초기값이 지정되지 않으면 배열의 첫 번째 요소가 초기값이 됩니다.
반환값
- reduce()는 누적된 단일 값을 반환합니다.
+ 예제 : 배열에서 최대값 찾기
const numbers = [1, 9, 3, 7, 2];
const max = numbers.reduce((acc, curr) => (acc > curr ? acc : curr));
console.log(max); // 출력: 9
⭐️중요: 현업에서 자주 사용되는 이유
- 원본 유지: 데이터의 무결성을 유지할 수 있어 코드의 안전성이 높습니다.
- 불변성 유지: 불변성 원칙을 지키면서 데이터를 관리할 수 있어, 특히 리액트 같은 프레임워크에서 유리합니다.
- 가독성 향상: 데이터가 변경되지 않으므로 데이터 흐름이 명확하게 유지됩니다.
➕현업에서 자주 쓰이는 메서드와 안 쓰이는 메서드
- 자주 쓰이는 메서드
- map(), filter(), reduce(), concat(), slice()
- 이유: 원본 배열을 변경하지 않고 새로운 배열을 반환하여 데이터의 일관성을 유지하기 때문에 협업 환경에서 많이 사용됩니다.
- 자주 안 쓰이는 메서드
- push(), pop(), splice(), sort(), reverse()
- 이유: 원본 배열을 직접 수정하여 데이터 변경을 추적하기 어렵고, 실수로 데이터가 오염될 수 있는 위험이 있습니다.
실무 팁✨
- 불변성을 유지하라: 항상 새로운 데이터를 반환하는 메서드를 사용하여 원본 데이터를 유지하는 것이 중요합니다!
- 배열 수정은 최소화: push()와 같은 메서드는 필요한 경우에만 신중하게 사용하고, 가능하다면 concat()을 사용해 새 배열을 반환하도록 코드를 작성하세요.
- 명확한 데이터 흐름 유지: 데이터가 어떻게 변형되는지 명확하게 이해하고, 의도하지 않은 데이터 변경을 막아야 합니다.