키를 이용해 값을 식별하는 것을 컬렉션 이라고 하며 객체라는 자료구조로 저장합니다.
하지만 객체는 순서를 고려하도록 만들어진 자료구조가 아니므로, 순서가 있는 컬렉션을 다룰 때 배열 자료구조를 사용합니다.
배열 요소의 자료형엔 제약이 없어, 하나의 배열 변수에 여러 가지 자료형이 올 수 있습니다.
즉, 하나의 배열이 객체, 숫자, 문자열... 등 모든 자료형을 같이 담을 수 있습니다.
let arr = new Array();
let arr = [];
대부분 두 번째 방법으로 대괄호를 이용하여 선언합니다.
let fruits = ["사과", "오렌지", "자두"];
선언하며 초기화하는 것도 가능합니다.
각 배열 요소는 0부터 시작하는 인덱스가 매겨지며, 이는 배열 내 순서를 나타냅니다. 각 배열 요소는 인덱스를 사용하여 얻을 수 있습니다.
let fruits = ["사과", "오렌지", "자두"];
alert( fruits[0] ); // 사과
alert( fruits[1] ); // 오렌지
alert( fruits[2] ); // 자두
대괄호 안에 인덱스를 넣어 해당 요소를 불러옵니다.
fruits[2] = '배';
인덱스를 지정 후 값을 할당하면 배열 요소를 수정할 수 있습니다.
fruits[3] = '레몬';
값이 없는 인덱스에 값을 할당하면 새로운 요소를 추가할 수 있습니다.
length 를 이용하여 배열의 길이를 알아낼 수 있습니다.
let fruits = [];
fruits[123] = "사과";
alert( fruits.length ); // 124
배열을 사용하여 스택(stack) 과 큐(queue) 자료구조를 만들 수 있습니다.
두 자료구조는 내장 메서드를 이용하여 구현됩니다.
LIFO)push : 맨 끝에 요소를 추가pop : 맨 끝에 있는 요소를 추출FIFO)push : 맨 끝에 요소를 추가shift : 제일 앞 요소를 추출 후 남아있는 요소를 앞으로 밀어줌unshift : 맨 앞에 요소를 추가unshift 와 shift 는 배열의 맨 앞에서, push 나 pop 은 배열의 맨 끝에서 요소를 추가, 제거하는 메서드입니다.
연산 흐름에 의해 push 와 pop 은 빠르고 간단하지만 unshift 와 shift 는 관련 연산이 많아 느립니다.
대괄호를 이용하여 요소에 접근하는 방식은 객체 문법에서 왔지만, 객체는 key 를 이용하고 배열은 숫자(인덱스) 를 이용한다는 점이 다릅니다.
숫자형 키(인덱스) 를 사용함으로써 배열은 순서가 있는 컬렉션을 제어하도록 하는 특수 메서드를 제공합니다. 그러나, 배열의 본질은 객체라고 볼 수 있습니다.
즉, 배열은 객체형에 속하며 객체처럼 동작합니다.
배열은 객체처럼 참조를 통해 복사됩니다.
let fruits = ["바나나"]
let arr = fruits; // 참조를 복사함(두 변수가 같은 객체를 참조)
alert( arr === fruits ); // true
arr.push("배"); // 참조를 이용해 배열을 수정
alert( fruits );
// 두 변수가 같은 참조값을 지니므로 하나만 수정해도 수정 결과가 둘 다에 반영됨
이렇듯, 복사를 할 때 값 자체가 복사되는 것이 아니라 그 객체에 대한 참조값이 복사됩니다.
자바스크립트 엔진은 배열 요소를 인접한 메모리 공간에 차례로 저장하여 연산 속도를 높이는 등 다양한 최적화 기법을 사용합니다.
그런데, 배열을 일반 객체처럼 다루면 제대로 최적화되지 않습니다.
let fruits = [];
fruits[99999] = 5;
// 배열의 길이보다 훨씬 큰 숫자를 사용해 프로퍼티 생성
fruits.age = 25;
// 임의의 이름을 사용해 프로퍼티 생성 (숫자키 ❌)
이렇듯... 요소를 차례대로 채우지 않거나 숫자가 아닌 값을 프로퍼티 키로 사용하는 등 잘못된 방식으로 배열을 사용하면 안됩니다.
배열을 순회하는 반복문에는 두 가지 방법이 있습니다.
for..of 로 배열의 값을 얻어 순회하거나
let fruits = ["사과", "오렌지", "자두"];
// 배열 요소를 대상으로 반복 작업을 수행합니다.
for (let fruit of fruits) {
alert( fruit );
}
for..in 으로 키값을 얻어 순회합니다.
배열이 객체형에 속하므로 for..in 을 사용할 수 있습니다.
let arr = ["사과", "오렌지", "배"];
for (let key in arr) {
alert( arr[key] ); // 사과, 오렌지, 배
}
배열에는 되도록 for..in 말고 for..of 를 사용하는 게 좋습니다.
왜냐하면...
for..in 의 특징for..in 은 모든 프로퍼티를 대상으로 순회. 키가 숫자(배열형태)가 아니더라도 반복문의 대상으로 집어넣음! 유사배열의 경우 문제❗for..in 은 객체 반복에 적합하지 배열에는 적합하지 ❌위처럼, 유사배열의 경우 모든 프로퍼티 순회에 대한 문제가 성능 문제가 있기 때문입니다. 가급적이면 for..of 를 사용하여 배열을 순회합시다.
배열의 길이를 나타내는 length 프로퍼티는 배열의 길이가 변함에 따라
자동으로 갱신되는 프로퍼티입니다.
length 는 배열 내 요소의 총 개수가 아니라 배열에 요소가 존재하는
가장 큰 인덱스에 1을 더한 값입니다.
따라서 실제 담긴 요소는 얼마 없어도 length 의 값은 아주 커질 수 있습니다.
let fruits = [];
fruits[123] = "사과";
alert( fruits.length ); // 124
// fruits[123] 에만 값이 들어있지만 길이는 124!!
length 프로퍼티는 쓰기가 가능한 값입니다.
let arr = [1, 2, 3, 4, 5];
arr.length = 2; // 요소 2개만 남기고 잘라봅시다.
alert( arr ); // [1, 2]
arr.length = 5; // 본래 길이로 되돌려 봅시다.
alert( arr[3] ); // undefined: 삭제된 기존 요소들이 복구되지 않습니다.
length 값을 변경하면, 배열의 길이가 바뀌고 안에 있는 요소들도 삭제됩니다.
이를 이용하여, arr.length = 0; 을 사용하여 배열을 비울 수 있습니다.
배열의 요소로 배열을 할당할 수 있습니다.
행렬을 저장하는 용도로 사용합니다.
let matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
alert( matrix[1][1] ); // 5, 중심에 있는 요소
배열에는 toString 메서드가 구현되어 있어 이를 사용해 문자열로 변환할 수 있습니다.
let arr = [1, 2, 3];
alert( arr ); // 1,2,3
alert( String(arr) === '1,2,3' ); // true
배열을 출력하면 배열 요소가 쉼표로 구분되어 문자열로 출력됩니다.
배열엔 Symbol.toPrimitive 나 valueOf 메서드가 없으므로
숫자와 사칙연산을 하면 다른 피연산자도 문자열로 변환되어 반환합니다.