
여러 개의 값을 순차적으로 나열한 자료구조
배열의 각각의 값 : 요소
배열에서 값의 위치 : 인덱스
배열의 길이 : length 프로퍼티
자바스크립트의 배열은 객체 타입이다
배열의 생성자 함수는 Array, 프로토타입은 Array.prototype이다
배열은 일반 객체와 다르게 '값의 순서'와 'length 프로퍼티'를 갖는다
반복문으로 자료구조를 순회하기 위해서는 자료구조의 순서와 길이를 알아야 한다
배열은 인덱스와 length 프로퍼티가 있기에 가능하다

일반적인 배열 : 하나의 데이터 타입으로 동일한 크기의 메모리 공간이 연속적으로 나열된 자료구조 (밀집배열)
그렇기 때문에 인덱스를 통해 O(1)로 요소에 접근이 가능한것
원하는 요소의 메모리 주소 = 배열의 시작 메모리 주소 + 인덱스 * 요소 바이트 수
특정 요소를 찾을 때에는 처음부터 찾을때까지 검색해야해서 O(N)
배열에 요소를 삽입,삭제 시 연속적으로 유지하기 위해 요소를 이동시켜야함

위와 같은 일반적인 배열과 자바스크립트의 배열은 다르다
배열의 요소를 위한 각각의 메모리 공간이 동일한 크기를 갖지 않아도 되고, 연속적으로 이어져있지 않을 수도 있다
자바스크립트의 배열은 일반적인 배열의 동작을 흉내 낸 특수한 객체
사실 자바스크립트의 배열은 인덱스가 프로퍼티 키이고 요소가 프로퍼티 값인 객체
length프로퍼티도 갖고있는 객체이다
대부분의 모던 자바스크립트 엔진은 배열을 일반 객체와는 구별하여 최적화를 시켜놔서 일반 객체보다는 빠르다
배열에 요소를 추가하거나 삭제하면 자동으로 갱신된다
const arr = [1,2];
arr.length; // 2
arr.push(3);
arr.length; // 3
arr.pop();
arr.length // 2
length 프로퍼티의 값은 요소의 개수에 따라 결정되지만 임의로 할당도 가능
현재 배열의 길이보다 작은 length를 할당하면 새로운 length에 맞게 배열이 줌
const arr = [1,2,3,4,5];
arr.length = 2;
arr; // [1,2]
배열 길이보다 큰 값을 length 프로퍼티에 할당하면
length 프로퍼티의 값은 바뀌지만 실제 배열에는 변화가 없다
비어있는 요소를 위해 메모리 공간을 확보하지 않고 빈 요소를 생성하지도 않음

배열의 요소 일부가 비어 있는 배열을 희소 배열이라고 함
자바스크립트는 문법적으로 희소 배열을 허용
희소배열은 length와 요소의 개수가 일치하지 않는다
const arr = [1, ,2, ,4];
arr.length; // 5
최적화가 잘 되어있는 모던 자바스크립트 엔진은 동일한 타입의 요소를 갖는 배열을 생성할 때 일반적인 배열처럼 연속된 메모리 공간을 확보한다
배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 좋다
const arr = [1,2,3];
const arr2 = [];
const arr3 = [1, ,2]; // 희소 배열
arr3[1]; // undefined, arr3객체에 프로퍼티 키가 '1'인 프로퍼티가 없음
new 연산자 없이 호출해도 괜찮 (Array 생성자 함수에서 new.target으로 처리)
const arr = new Array(10); // 요소는 없음, 그냥 arr.length만 10임
const arr = new Array(1,2,3); // [1,2,3]
const arr2 = new Array('apple'); // ['apple']
ES6 도입
전달된 인수를 요소로 갖는 배열 생성
인수 1개여도 똑같이 ( 생성자 함수는 인수 1개면 length가 인수인 배열 생성)
Array.of(1); // [1]
Array.of('apple'); // ['apple']
Arrray.of(1,2,3,4,5); // [1,2,3,4,5]
ES6 도입
유사 배열 객체, 이터러블 객체를 인수로 받아 배열로 변환후 반환
두번째 인수로 콜백 함수를 전달하면 첫번째 인수로 생성한 배열의 요소와 인덱스를 순서대로 콜백함수에게 전달하며 호출한 뒤 콜백 함수의 반환값으로 구성된 배열을 반환
Array.from({length:3,0:'a',1:'b',2:'c'}); // ['a','b','c']
Array.from('Hello'); // ['H','e','l','l','o']
Array.from({length:3}); // [undefined,undefined,undefined]
Array.from({length:3},(item,idx)=>idx); // [0,1,2]
유사 배열 객체 : 배열처럼 인덱스로 프로퍼티 값에 접근하고, length 프로퍼티를 갖는 객체
arr[인덱스] 로 참조
존재하지 않는 인덱스에 접근 시 undefined 반환
사실 프로퍼티이기 때문에 객체의 없는 프로퍼티에 접근하면 undefined 반환 하는것과 똑같음
존재하지 않는 인덱스에 값을 할당하여 동적 추가 가능
length 프로퍼티는 자동 갱신
const arr = [1,2];
arr[2] = 3;
arr; [1,2,3]
arr[4] = 5; //length 프로퍼티보다 큰 인덱스에 할당하면 희소 배열 됨
arr; // [1,2,3,empty,5]
인덱스는 반드시 0이상의 정수(정수 형태의 문자열)만 가능
이외의 값을 인덱스로 사용하면 프로퍼티로 추가가 된다
프로퍼티는 length에 영향 X
const arr = [1,2];
arr[-1] = -1;
arr['a'] = 100;
arr; // [1,2,-1:-1,'a':100]
arr.length; // 2
배열은 사실 객체이기 때문에 프로퍼티를 삭제하듯 delete 연산자로 삭제 가능
하지만 length 프로퍼티는 갱신이 되지 않아 희소 배열이 되는 문제 발생
const arr = [1,2,3];
delete arr[0];
arr; // [empty,2,3]
arr.length; // 3
배열 요소를 삭제할 때에는 Array.prototype.splice 메서드 사용
Array.prototype.splice(삭제를 시작할 인덱스,거기부터 삭제할 개수)
const arr = [1,2,3,4,5];
arr.splice(1,3);
arr; // [1,5]