배열은 여러 값을 순서대로 담아 두는 상자입니다. 가장 많이 헷갈리는 지점은 “이 메서드가 원본을 건드리는가”입니다. 자주 쓰는 배열 함수를 표로 정리하고 원본 변경 여부를 확인하는 사전입니다.
| 메서드 | 하는 일 | 반환값 / 원본 |
|---|---|---|
push(v) |
맨 뒤에 넣습니다 | 새 길이 / 변경 |
pop() |
맨 뒤 값을 빼냅니다 | 빼낸 값 / 변경 |
unshift(v) |
맨 앞에 넣습니다 | 새 길이 / 변경 |
shift() |
맨 앞 값을 빼냅니다 | 빼낸 값 / 변경 |
slice(a, b) |
일부를 복사합니다 | 새 배열 / 유지 |
splice(a, n) |
중간을 자릅니다 | 잘라낸 배열 / 변경 |
concat(arr) |
두 배열을 잇습니다 | 새 배열 / 유지 |
join(s) |
구분자로 잇습니다 | 문자열 / 유지 |
indexOf(v) |
값의 위치 | 숫자, 없으면 -1 |
includes(v) |
값이 있는지 | true / false |
find(f) |
조건에 맞는 첫 값 | 값, 없으면 undefined |
forEach(f) |
하나씩 훑습니다 | 없음 (undefined) |
map(f) |
모든 값을 변환 | 새 배열 / 유지 |
filter(f) |
조건에 맞는 값만 | 새 배열 / 유지 |
reduce(f, init) |
전체를 한 값으로 | 값 하나 / 유지 |
sort(f) |
순서대로 줄 세웁니다 | 같은 배열 / 변경 |
reverse() |
순서를 뒤집습니다 | 같은 배열 / 변경 |
f에 넘기는 함수를 콜백 함수라고 부릅니다. 문법이 낯설다면 자바스크립트 함수 편을 함께 보십시오.
넣고 빼기 — push, pop, unshift, shift
배열의 양 끝에서 값을 넣고 빼며, 넷 모두 원본을 직접 고칩니다.
const tags = ["코딩", "입문"];
console.log(tags.push("강좌")); // 3 — 넣은 값이 아니라 새 길이입니다
console.log(tags.pop()); // "강좌"
tags.unshift("추천");
console.log(tags); // ["추천", "코딩", "입문"]
console.log(tags.shift()); // "추천"
const 배열에도 값을 넣을 수 있습니다. 상자를 바꾸는 것이 아니라 안을 채우는 일이기 때문입니다.
자르고 붙이기 — slice, splice, concat, join
이름이 비슷한 slice와 splice가 정반대로 동작하므로 주의해야 합니다.
const posts = ["1강", "2강", "3강", "4강", "5강"];
console.log(posts.slice(1, 3)); // ["2강", "3강"] 원본은 그대로 5개
console.log(posts.splice(1, 2)); // ["2강", "3강"] 잘라 낸 조각
console.log(posts); // ["1강", "4강", "5강"] 원본이 줄었습니다
const basic = ["변수", "함수"];
console.log(basic.concat(["배열"]).join(" > ")); // "변수 > 함수 > 배열"
console.log(basic); // ["변수", "함수"] 유지
slice는 복사, splice는 수술로 외워 두십시오. join은 배열을 문자열로 되돌리므로 이후 처리는 자바스크립트 문자열 함수 편으로 이어집니다.
찾고 훑기 — indexOf, includes, find, forEach
값이 있는지 확인하거나 전체를 훑는 묶음입니다.
const scores = [82, 95, 60, 77];
console.log(scores.indexOf(60)); // 2
console.log(scores.includes(100)); // false
console.log(scores.find(n => n >= 90)); // 95 (없으면 undefined)
scores.forEach((n, i) => console.log(i + "번: " + n));
// 0번: 82 / 1번: 95 / 2번: 60 / 3번: 77
find는 첫 값 하나만 돌려주므로 모두 모으려면 filter를 씁니다. forEach는 아무것도 돌려주지 않아 결과를 담아 봐야 undefined입니다.
새 배열을 만드는 map, filter, reduce
원본을 두고 가공 결과를 새로 받는 세 가지이며, 실무에서 많이 쓰입니다.
const prices = [1200, 3400, 800, 5000];
console.log(prices.map(p => p + "원")); // ["1200원","3400원","800원","5000원"]
console.log(prices.filter(p => p < 2000)); // [1200, 800]
console.log(prices.reduce((sum, p) => sum + p, 0)); // 10400
console.log(prices); // [1200, 3400, 800, 5000] 원본은 그대로
reduce의 두 번째 인자 0은 출발값이며, 빼먹으면 빈 배열에서 오류가 납니다. forEach의 결과를 변수에 담는 실수도 흔한데, 새 배열이 필요하면 map을 씁니다.
정렬 — sort와 reverse, 그리고 숫자 정렬 함정
가장 많이 속는 부분입니다. sort()는 기본적으로 값을 문자열로 바꿔서 비교합니다.
const nums = [10, 9, 100, 2];
console.log([...nums].sort()); // [10, 100, 2, 9] 사전 순입니다
console.log([...nums].sort((a, b) => a - b)); // [2, 9, 10, 100] 숫자 정렬
const titles = ["나", "가", "다"];
titles.reverse();
console.log(titles); // ["다", "가", "나"] 원본이 뒤집혔습니다
둘 다 원본 자체를 줄 세운 뒤 그 배열을 돌려줍니다. 위처럼 [...배열]로 복사본을 만들면 원본이 안전합니다.
핵심 정리
- 원본 변경 — push, pop, shift, unshift, splice, sort, reverse
- 원본 유지 — slice, concat, map, filter, reduce
- slice와 splice — 복사와 수술로 구분하십시오.
- sort의 함정 — 숫자 정렬에는
(a, b) => a - b가 필요합니다. - map과 forEach — 결과 배열이 필요하면 map