Array Additions
배열(Array) 객체에 새롭게 추가된 클래스 또는 스태틱(static), 인스턴스 메서드에 대해 정리합니다.
영상 강의
PART 1
PART 2
예제
Array.from()
기존 코드는 유사 배열을 배열화 한 후 배열의 메서드를 사용했습니다.
// DOM 객체 수집(Collection) = NodeList
// lis 변수에 참조된 값은 length 속성을 가진 유사 배열 객체
var lis = document.querySelectorAll('ul.demo li');
// 유틸리티 함수
function makeArray(o) {
return Array.prototype.slice.call(o);
}
// 유틸리티 함수 makeArray()를 사용하여 lis 유사 배열을 배열로 변경
makeArray(lis).forEach(function (li) {
console.log(li); // <li> 순환
});
ES6+ 부터는 기본 제공되는 Array.from
클래스 메서드를 사용해 손쉽게 유사 배열을 배열화할 수 있습니다.
// DOM 객체 수집(Collection) = NodeList
// lis 변수에 참조된 값은 length 속성을 가진 유사 배열 객체
var lis = document.querySelectorAll('ul.demo li');
// Array.from() 네이티브 Array 메서드를 사용하여 lis 유사 배열을 배열로 변경
Array.from(lis).forEach(li => console.log(li)); // <li> 순환
Array.of()
new Array()
구문 사용 시 주의할 점은 객체 생성 과정에서 전달된 첫번째 아이템이 숫자일 경우
전달된 개수만큼 아이템이 생성되는 의도치 않는 문제가 발생한 점입니다.
var arr = new Array(3); // [undefined, undefined, undefined]
NOTE
이러한 문제를 마주치지 않기 위해 배열 리터럴 사용을 권장합니다.
var arr = [3];
ES6+ 부터는 Array.of()
구문을 사용해 전달된 첫번째 아이템이 숫자일 경우에도
의도치 않는 문제가 발생하지 않습니다.
const arr = Array.of(3); // [3]
Array.prototype.keys()
기존 코드는 for문 또는 배열의 .forEach()
메서드를 사용해 배열 데이터를 순환 처리하였습니다.
var numbers = [100, 105, 103, 109];
// for문
for ( var i=0, l=numbers.length; i<l; i++ ) {
console.log(i, numbers[i]);
// 0, 100
// 1, 105
// 2, 103
// 3, 109
}
// forEach문
numbers.forEach(function(n, i) {
console.log(i, n);
// 0, 100
// 1, 105
// 2, 103
// 3, 109
});
ES6+ 부터는 배열에 for .. of문을 사용하여 데이터를 순환 처리할 수 있습니다.
for (let number of numbers) {
console.log(number);
// 100
// 105
// 103
// 109
}
만약 데이터의 값이 아닌 인덱스 키를 출력하고자 한다면 배열 객체의 .keys()
메서드를 사용합니다.
for (let index of numbers.keys()) {
console.log(index);
// 0
// 1
// 2
// 3
}
Array.prototype.values()
배열 데이터의 값을 순환 처리하고자 할 경우, 배열 객체의 .values()
메서드를 사용할 수 있지만
배열을 순환 처리한 결과와 동일하기에 굳이 이런 방법을 사용할 필요는 없습니다.
for (let value of numbers.values()) {
console.log(value);
// 100
// 105
// 103
// 109
}
Array.prototype.entries()
배열 데이터의 각 아이템 인덱스와 값이 모두 필요한 경우라면 .entries()
메서드를 사용할 수 있습니다.
순환된 각 아이템은 인덱스와 값을 포함한 배열을 반환합니다.
for (let item of numbers.entries()) {
console.log(item);
// [0, 100]
// [1, 105]
// [2, 103]
// [3, 109]
}
구조 분해 할당을 활용하면 아래 코드처럼 인덱스와 값을 참조하는 변수를 설정할 수 있습니다.
for (let item of numbers.entries()) {
let [index, number] = item;
console.log(index, number);
// 0, 100
// 1, 105
// 2, 103
// 3, 109
}
구조 분해 할당 구문을 직접 for .. of문에 삽입하여 사용할 수도 있습니다.
for (let [index, number] of numbers.entries()) {
console.log(index, number);
// 0, 100
// 1, 105
// 2, 103
// 3, 109
}
Array.prototype.find()
기존 코드는 배열의 아이템 중 매칭되는 특정 아이템을 찾기 위해 별도로 헬퍼 함수를 만들어 사용했습니다.
var numbers = [100, 105, 103, 109];
// 배열 아이템을 찾는 유틸리티 함수
function findItemArray(array, cb) {
for ( var i=0, l=array.length; i<l; i++ ) {
if ( cb(array[i], i, array) ) { return array[i] }
}
}
// 유틸리티 함수를 사용해 조건에 부합하는 첫번째 아이템 반환
var item = findItemArray(numbers, function(item, index, array) {
return item > 100 && item < 105;
});
console.log(item); // 103
ES6+ 부터는 .find()
메서드를 사용해 손쉽게 매칭되는 첫번째 아이템을 찾을 수 있습니다.
numbers.find(number => number > 100 && number < 105); // 103
Array.prototype.findIndex()
기존 코드는 배열의 아이템 중 매칭되는 특정 아이템의 인덱스를 찾기 위해 별도로 헬퍼 함수를 만들어 사용했습니다.
var numbers = [100, 105, 103, 109];
// 배열 아이템 인덱스를 찾는 유틸리티 함수
function findItemIndexArray(array, cb) {
for ( var i=0, l=array.length; i<l; i++ ) {
if ( cb(array[i], i, array) ) { return i; }
}
return -1;
}
// 유틸리티 함수를 사용해 조건에 부합하는 첫번째 아이템 인덱스를 반환
var item = findItemIndexArray(numbers, function(item) {
return item > 105;
});
console.log(item); // 3
ES6+ 부터는 .findIndex()
메서드를 사용해 손쉽게 매칭되는 아이템의 인덱스를 찾을 수 있습니다.
numbers.findIndex(number => number > 105); // 3
indexOf vs findIndex
indexOf
와 findIndex
은 아이템의 인덱스를 반환한다는 점에서 비슷해보이지만,
매칭되는 값을 비교하는 처리에서 다소 차이가 있습니다. indexOf
는 완전하게 동일한 값을
비교하여 인덱스를 반환하는 반면, findIndex
는 전달되는 콜백함수 내부에서 비교(예: Object.is()) 조건을
설정하여 특정 조건에 매칭되는 값의 인덱스를 반환 받을 수 있습니다.
// Array.prototype.indexOf
// === 비교
// NaN === NaN // false
[false, 10, NaN, {}].indexOf(NaN); // -1
// Array.prototype.findIndex
// Object.is() 비교
// Object.is(NaN, NaN) // true
[false, 10, NaN, {}].findIndex(x => Object.is(x, NaN)); // 2
Array.prototype.includes()
기존 코드는 특정 아이템이 배열의 아이템인지 알아내기 위해 별도로 헬퍼 함수를 만들어 사용했습니다.
var numbers = [100, 105, 103, 109];
// 배열 아이템이 포함 되었는지 확인하는 유틸리티 함수
function isIncludeItemArray(array, item) {
return array.indexOf(item) > -1;
}
// 유틸리티 함수를 사용해 아이템이 포함 되었는지 유무 확인
if ( !isIncludeItemArray(numbers, 107) ) {
numbers.push(107);
}
ES6+ 부터는 .includes()
메서드를 사용해 손쉽게 아이템의 포함 유무를 확인할 수 있습니다.
if (!numbers.includes(107)) {
numbers.push(107);
}
Array.prototype.fill()
기존 코드는 특정 아이템으로 배열의 아이템을 모두 채우거나 특정 범위만 채우고자 할 경우 별도로 헬퍼 함수를 만들어 사용했습니다.
var numbers = [100, 105, 103, 109];
// 배열 아이템을 모두 동일하게 채우는 유틸리티 함수
function fillItemArray(array, item, start, end) {
start = start || 0;
end = end || array.length;
return array.map(function(t, i){
if ( i >= start && i < end ) {
return item;
} else {
return t;
}
});
}
// 유틸리티 함수를 사용해 배열 아이템을 모두 교체
fillItemArray(numbers, {}); // [{}, {}, {}, {}]
// 유틸리티 함수에 start, end 인자를 전달하면
// 조건에 부합하는 아이템만 교체
fillItemArray(numbers, {}, 1, 3); // [100, {}, {}, 109]
ES6+ 부터는 .fill()
메서드를 사용해 손쉽게 배열의 모든 아이템 또는 특정 범위의 아이템을 채울 수 있습니다.
const numbers = [100, 105, 103, 109];
// Array.prototype.fill 메서드를 사용해 배열 아이템을 모두 교체
numbers.fill({}); // [{}, {}, {}, {}]
// Array.prototype.fill 메서드를 사용해 배열 아이템을 부분 교체
numbers.fill({}, 1, 3); // [100, {}, {}, 109]
Array.prototype.copyWithin()
ES6+ 부터 사용 가능한 .copyWithin()
메서드는 배열의 일부를 얕게 복사한 뒤,
동일한 배열의 다른 위치에 덮어쓰고 그 배열을 반환합니다. 이 때, 크기(배열의 길이)를 수정하지 않고 반환합니다.
var numbers = [100, 105, 103, 109];
// Array.prototype.copyWithin(target, start=0, end=this.length)
// 0부터 (4-1)까지 아이템을 복사한 후, 1 위치부터 붙여넣음
numbers.copyWithin(1); // target: 1, start: 0, end: 4
// [100, 105, 103, 109] → [100, 100, 105, 103]
// 0부터 (4-1)까지 아이템을 복사한 후, -2(끝에서 2번째) 위치부터 붙여넣음
numbers.copyWithin(-2); // target: -2, start: 0, end: 4
// [100, 105, 103, 109] → [100, 105, 100, 105]
// 2부터 (4-1)까지 아이템을 복사한 후, 1 위치부터 붙여넣음
numbers.copyWithin(1, 2); // target: 1, start: 2, end: 4
// [100, 105, 103, 109] → [100, 103, 109, 109]
// 1부터 (2-1)까지 아이템을 복사한 후, 2 위치부터 붙여넣음
numbers.copyWithin(2, 1, 2); // target: 2, start: 1, end: 2
// [100, 105, 103, 109] → [100, 105, 105, 109]
// -2부터 -3까지 아이템을 복사한 후, -3(끝에서 3번째) 위치부터 붙여넣음
numbers.copyWithin(-3, -2); // target: -2, start: -2, end: 4
// [100, 105, 103, 109] → [100, 103, 109, 109]
참고
← Symbol Array Useful →