자바스크립트에서 배열을 다루는 방법과 유사 객체 배열에 대해 알아보자.
배열 생성
배열은 정수 인덱스를 가지는 순회와 조작 작업을 수행하는 객체이다. 생성 방법은 아래 두 가지가 있다.
Array() 생성자 사용
Array()
생성자 함수는 새로운 배열을 생성하고 인자로 받은 값들을 배열 요소로 채워 넣어 초기화한다. 단, 인자가 하나 뿐이고 자료형이 숫자라면 해당 값을 length 속성에 할당해 새 배열을 생성한다. 이 경우, 그 길이만큼 빈 슬롯을 가지는 것이지 undefined 값이 채워지는 것은 아니다.
const arr1 = new Array(1, 2);
console.log(arr1); // [1, 2]
const arr2 = new Array(2);
console.log(arr2); // [empty, empty]
배열 리터럴 방식
대괄호([])
를 사용해 배열을 생성하고 초기화한다. 위 방법보다 간단하여 더 자주 쓰이는 방법이다.
const arr = [1, 2, 3];
console.log(arr); // [1, 2, 3]
배열 요소 접근
인덱스로 요소 접근
배열 요소에 접근하고 싶다면 대괄호([]) 안에 인덱스 값을 넣으면 된다. 만약, 배열의 length 보다 큰 인덱스 값을 넣으면 undefined를 반환한다. 또한, 원하는 인덱스 값을 넣어 요소를 추가할 수도 있다.
length
length 속성은 배열의 길이를 반환한다. 반환값은 중간값이 빈 배열이라도 최대 인덱스 + 1로 배열의 최대 인덱스보다 항상 크다. 값을 할당할 경우 배열의 길이를 변경한다.
const arr = [1, 2, 3]; console.log(arr.length); // 3
const animals = ["dog", "cat", "mouse"];
console.log(animals[0]); // dog
console.log(animals[animals.length - 1]); // mouse
console.log(animals[3]); // undefined
animals[3] = "hedgehog";
console.log(animals); // ['dog', 'cat', 'mouse', 'hedgehog']
인덱스 찾기
indexOf()
배열에서 지정된 요소를 찾아 가장 처음에 위치한 인덱스를 반환하고 요소가 존재하지 않으면 -1을 반환한다.
const arr = [0, 1, 2, 4, 2];
console.log(arr.indexOf(4)); // 3
console.log(arr.indexOf(2)); // 2
console.log(arr.indexOf(5)); // -1
배열 조작
배열은 내장 메서드로 요소를 조작할 수 있다. 배열의 원본 데이터를 직접 수정하는 메소드와 기존 데이터를 조작해 새로운 배열을 생성하는 메서드 두 가지로 나뉜다.
원본 데이터 직접 수정
push()
배열의 마지막에 하나 이상의 요소를 추가하고, 배열의 변경된 length를 반환한다.
const arr = [1, 2];
console.log(arr.push(3, 4)); // 4
console.log(arr); // [1, 2, 3, 4]
pop()
배열에서 마지막 인덱스에 해당하는 요소를 추출하고 그 값을 반환한다.
const arr = [1, 2];
console.log(arr.pop()); // 2
console.log(arr); // [1]
shift()
배열의 첫 번째 요소를 삭제하고, 삭제된 요소를 반환한다.
const arr = [1, 2];
console.log(arr.shift()); // 1
console.log(arr); // [2]
unshift()
배열의 처음에 요소를 추가하고, 배열의 변경된 length를 반환한다.
const arr = [1, 2];
console.log(arr.unshift(-1, 0)); // 4
console.log(arr); // [-1, 0, 1, 2]
splice()
배열의 기존 요소를 삭제 또는 교체, 추가하여 원본 배열을 변경한다. 첫 번째 인자는 시작 인덱스, 두 번째 인자는 제거할 요소의 수, 마지막 인덱스는 배열에 추가할 요소이다.
const arr = [1, 3, 4, 5];
arr.splice(1, 0, 2);
console.log(arr); // [1, 2, 3, 4, 5]
sort()
배열의 요소들을 인자로 받은 함수를 사용해 정렬한다. 함수가 생략된 경우, 각 문자의 유니코드 값에 따라 정렬되며 숫자 역시 문자로 변환하여 정렬된다.
const arr = [4, 3, 22, 58, 5];
arr.sort();
console.log(arr); // [22, 3, 4, 5, 58]
새로운 배열 생성
concat()
인자에 해당하는 배열이나 값들을 기존 배열과 합쳐 새로운 배열을 반환한다. 원본 배열은 변하지 않는다.
const arr1 = [1, 2, 3];
const arr2 = arr1.concat([4, 5, 6]);
console.log(arr1); // [1, 2, 3, 4, 5, 6]
slice()
배열에서 특정 범위의 요소를 복사하여 새로운 배열로 반환한다. 그러나 얕은 복사이므로 배열의 요소가 객체라면 참조가 그대로 유지되니 주의해야 한다. 첫 번째 인자는 시작 인덱스, 두 번째 인자는 마지막 인덱스이고 마지막 인덱스는 포함하지 않고 그 전까지만 복사된다.
얕은 복사(Shallow Copy)
대상 객체를 새로 생성하지만 내부에 중첩된 객체는 새로 생성하지 않고 동일한 객체를 참조한다.
깊은 복사(Deep Copy)
중첩된 객체까지 모두 새로 생성한다.
const arr = [1, 2, 3];
console.log(arr.slice(1, 2)); // 2
펼침 연산자(Spread Operator)로도 slice()와 같이 얕은 복사를 할 수 있다.
const arr1 = [1, 2, 3];
console.log([...arr]); // [1, 2, 3]
순환 배열
forEach()
인자로 받은 함수가 배열 요소 각각을 순회하면서 실행된다.
const arr = [0, 1, 2];
arr.forEach(x => console.log(x));
map()
배열 내 모든 요소를 인자로 받은 함수로 실행된 결과를 모아 새로운 배열로 반환한다.
const arr = [0, 2, 4];
const mapArr = arr.map(x => x + 2);
console.log(mapArr); // [2, 4, 6]
filter()
인자로 받은 함수의 테스트를 통과하는 배열 요소를 모아 새로운 배열로 반환한다.
const arr = [0, 2, 4];
const filterArr = arr.filter(x => x < 4);
console.log(filterArr); // [0, 2]
유사 배열 객체
배열처럼 사용할 수 있는 일반 객체를 유사 배열 객체라고 한다. length 속성 값이 양의 정수인 객체여야만 한다. 대표적으로 arguments가 있다.
function func(a, b, c) {
console.log(arguments[0], arguments[1], arguments[2]); // 1, 2, 3
console.log(arguments.length); // 3
}
func(1, 2, 3);
arguments
함수에 전달한 인자를 유사 배열 객체로 만든 데이터이다.
arguments 객체는 마치 배열처럼 인덱스로 프로퍼티에 접근할 수 있으며, length 프로퍼티를 가지지만 유사 배열 객체이므로 배열의 내장 메서드는 사용할 수 없다. 그래서 배열의 내장 메서드를 call() 또는 apply() 함수와 결합해 사용한다.
function func(a, b, c) {
Array.prototype.forEach.call(arguments, arg => {
console.log(arg);
});
}
func(1, 2, 3);
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array#constructor