모던 JavaScript 튜토리얼 내용 중 일부 문제를 정리한 내용입니다.
배열의 요소를 추가, 삭제, 교체하고 싶다면 splice 메서드를 사용합니다.
arr.splice(index[, deleteCount, elem1, ..., elemN])
index 는 조작을 가할 첫 번째 요소를 가리키고, deleteCount 는 제거하려는 요소의 개수를 나타냅니다. elem1, ..., elemN 은 배열에 추가할 요소를 나타냅니다. 기존 배열은 수정되고, splice 자체는 삭제된 요소로 구성된 배열을 반환하니 유의합니다.
// 기존 배열의 요소를 제거
let arr = ["I", "study", "JavaScript"];
arr.splice(1, 1);
alert( arr ); // ["I", "JavaScript"]
// splice 자체는 삭제된 요소를 배열로 반환
let arr = ["I", "study", "JavaScript", "right", "now"];
let removed = arr.splice(0, 2);
alert( removed ); // "I", "study"
// 삭제하고 추가하는 경우
let arr = ["I", "study", "JavaScript", "right", "now"];
arr.splice(0, 3, "Let's", "dance");
alert( arr ) // ["Let's", "dance", "right", "now"]
// 삭제하지 않고 추가하는 경우, 두번째 인자 0으로
let arr = ["I", "study", "JavaScript"];
arr.splice(2, 0, "complex", "language");
alert( arr ); // "I", "study", "complex", "language", "JavaScript"
arr.slice 는 arr.splice 와 유사하지만 더 간단합니다.
arr.slice([start], [end])
start 인덱스 부터 end 인덱스 앞까지의 요소를 복사한 새로운 배열을 반환합니다. arr.slice() 처럼 인수에 값을 넣지 않고 arr 의 복사본을 만들면, 기존 배열을 건드리지 않고 새로운 배열을 만들 수 있습니다.
let arr = ["t", "e", "s", "t"];
let newArr = arr.slice() // 복사본 새로운 배열로 생성
alert( arr.slice(1, 3) ); // e,s
alert( arr.slice(-2) ); // s,t 음수일 경우 배열 끝에서부터 요소 개수 셈
arr.concat 은 기존 배열의 요소를 사용해 새로운 배열을 만들거나 기존 배열에 요소를 추가할 때 사용합니다.
arr.concat(arg1, arg2 ...)
arr 의 모든 요소와 argN 에 속한 모든 요소가 모여 새로우 배열이 반환됩니다. 배열이 들어온다면 모든 요소가 복사되고 객체를 인자로 받으면 객체가 통으로 복사됩니다.
let arr = [1, 2];
alert( arr.concat([3, 4]) ); // 1,2,3,4
alert( arr.concat([3, 4], [5, 6]) ); // 1,2,3,4,5,6
alert( arr.concat([3, 4], 5, 6) ); // 1,2,3,4,5,6
// 객체의 경우 분해되지 않고 결합
let arr = [1, 2];
let arrayLike = {
0: "something",
length: 1
};
alert( arr.concat(arrayLike) ); // 1,2,[object Object]
밸로퍼트 모던 리액트 예제에서는 아래와 같이 사용합니다.
const [users, setUsers] = useState([
{
id: 1,
username: 'velopert',
email: 'public.velopert@gmail.com',
active: true,
},
]);
..
const onCreate = () => {
const user = { // 사용자가 입력한 새로운 객체
id: nextId.current,
username,
email,
};
setUsers(users.concat(user)); // 여기서 사용
};
arr.forEach 는 배열 요소를 순회하며 주어진 함수를 실행합니다.
// 기본 형태
arr.forEach(function(item, index, array) {
// 요소에 무언가를 할 수 있습니다.
});
// 값을 출력해본다면,
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
alert(`${item} is at index ${index} in ${array}`);
});
arr.indexOf(item, from) 은 인덱스 from 부터 시작해 item 을 찾아, 해당 요소의 인덱스를 반환합니다. 발견하지 못하면 -1 을 반환합니다. arr.lastIndexOf(item, from) 은 같은 기능을 수행하는데 검색을 끝에서 부터 합니다. arr.includes(item, from) 은 from 부터 시작해 Item 이 있는지 검색하고 있으면 true 없으면 false 를 반환합니다. 요소가 배열 내 존재하는지 여부만 확인한다면 Includes 를 사용하는 게 좋습니다.
let arr = [1, 0, false];
arr.indexOf(0); // 1
arr.indexOf(false); // 2 -- 완전 항등 연산자 === 로 비교, falsy 한 값이 아닌 false 체크
arr.indexOf(null); // -1
arr.includes(1); // true
특정 조건에 맞는 배열 내 객체를 찾고 싶다면 arr.find 를 사용합니다.
let result = arr.find(function(item, index, array) {
// true가 반환되면 반복이 멈추고 해당 요소를 반환
// 조건에 해당하는 요소가 없으면 undefined를 반환
});
함수는 배열의 요소를 받아 조건식으로 true 이면 해당 요소를 반환합니다. 해당 요소가 없으면 undefined 입니다. 아래 예시는 배열 내 id == 1 조건을 충족하는 사용자 객체를 찾습니다. 해당 id 를 찾으면 탐색을 중단합니다. id 값이 1 이 이후에 있어도 처음 찾은 값만 반환합니다.
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
let user = users.find(item => item.id == 1);
alert(user.name); // John
위와 같이 find 메서드를 사용하는 경우가 많으며, 두세번째 인자를 쓰는 경우는 별로 없습니다. findIndex 는 비슷하나 해당 요소가 아닌 해다 요소의 인덱스 값을 반환합니다.
find 는 조건에 맞는 요소를 하나만 찾아내지만 filter는 여러개 요소를 모두 찾습니다. filter 는 조건에 맞는 요소 전체를 담은 배열을 반환합니다.
let results = arr.filter(function(item, index, array) {
// 조건을 충족하는 요소는 results에 순차적으로 더해짐
// 조건을 충족하는 요소가 하나도 없으면 빈 배열이 반환
});
// 예시
let users = [
{id: 1, name: "John"},
{id: 2, name: "Pete"},
{id: 3, name: "Mary"}
];
// 앞쪽 사용자 두 명 반환
let someUsers = users.filter(item => item.id < 3);
someUsers.length; // 2
arr.map 은 사용 빈도가 높은 메서드입니다. 배열 요소 전체를 대상으로 함수를 호출하고, 그 결과를 새로운 배열로 반환합니다.
let result = arr.map(function(item, index, array) {
// 요소 대신 새로운 값을 반환
});
// 문자열 길이를 출력해서 배열로 반환
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length);
lengths; // [5,7,6]
arr.sort() 는 배열 요소를 정렬합니다. 이때 기존 배열 자체가 변경되며 재정렬된 배열 자체도 반환됩니다. sort 를 그대로 사용하면 문자열의 경우 사전편집 순으로 비교되어서 2가 15보다 크다고 취급됩니다. 새로운 정렬 기준을 적용하려면 arr.sort() 에 새로운 함수를 전달해야합니다. 아래는 숫자 오름차순 기준의 정렬입니다.
function compareNumeric(a, b) {
if (a > b) return 1;
if (a == b) return 0;
if (a < b) return -1;
}
let arr = [ 1, 2, 15 ];
arr.sort(compareNumeric);
alert(arr); // 1, 2, 15
// 양수를 반환하고 싶다면 아래처럼 첫번째 인수가 두번째 인수보다 크다고만 표현해도 됩니다.
let arr = [ 1, 2, 15 ];
arr.sort(function(a, b) { return a - b; });
// 화살표 함수르 사용하면 더 깔끔
arr.sort( (a, b) => a - b );
arr.reverse 는 arr 요소를 역순으로 정렬합니다.
let arr = [1, 2, 3, 4, 5];
arr.reverse();
arr; // 5,4,3,2,1
str.split(delim) 은 구분자 delim 을 기준으로 문자열을 쪼개서 배열에 담아줍니다. str.join은 그 반대 역할을 합니다.
let names = 'Bilbo, Gandalf, Nazgul';
let arr = names.split(', ');
arr; // [Bilbo, Gandalf, Nazgul]
// 문자열을 글자 단위로 분리할 수도 있음
let str = "test";
str.split(''); // t,e,s,t
// join 은 반대 역할
let arr = ['Bilbo', 'Gandalf', 'Nazgul'];
let str = arr.join(';');
alert( str ); // Bilbo;Gandalf;Nazgul
배열 기반으로 값 하나를 도출할 때 사용합니다.
let value = arr.reduce(function(accumulator, item, index, array) {
// ...
}, [initial]);
인수로 넘겨주는 함수는 배열의 모든 요소를 대상으로 적용되며 적용 졀과는 다음 함수 호출시 사용됩니다. accumulator 는 이전 함수의 호출결과이고 initial 은 함수 최초 호출 시 초깃값입니다.
let arr = [1, 2, 3, 4, 5];
let result = arr.reduce((sum, current) => sum + current, 0); // 초기 값 0 생략 가능
alert(result); // 15
reduce 는 보통 위 예제처럼 두개 인수를 받습니다. 함수 최초 호출 시 초기값 0 이 sum 에 할당되고 current 에는 배열 첫번째 요소 1이 할당됩니다. 두번째 호출에는 sum = 1 에 배열 두번째 요소 2가 더해져 3이 되고, 다음에는 3에 다음 요소가 더해집니다. 초기 값 0을 생략해도 되는데 그럴 경우 첫번째 값에 배열의 첫 번째 요소를 사용합니다. 이럴 경우 배열이 비어있다면 에러가 발생하니 주의해야 합니다.
배열은 객체형에 속하므로 typeof 로 구분할 수 없습니다. 이럴 때 Array.isArray() 를 사용하면 배열 여부를 확인할 수 있습니다.
alert(typeof {}); // object
alert(typeof []); // object
alert(Array.isArray({})); // false
alert(Array.isArray([])); // true
thisArg 는 선택적으로 사용할 수 있는 마지막 인수입니다.
arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
아래처럼 this 를 사용한 함수를 호출하는 경우 해당 this 에 해당하는 값을 넣어주어야 에러를 방지할 수 있습니다.
let army = {
minAge: 18,
maxAge: 27,
canJoin(user) {
return user.age >= this.minAge && user.age < this.maxAge;
}
};
let soldiers = users.filter(army.canJoin, army);