배열

</>·2022년 4월 23일
3
post-thumbnail

목표

  • 27장의 내용을 최대한 이해하고 정리하기

27. 배열


27-1. 배열이란?

const fruit = ['apple', 'banana', 'orange'];
  • 배열은 여러 개의 값을 순차적으로 나열한 자료구조이다.
  • 배열이 가지고 있는 값 하나하나를 요소(element) 라고 부른다.
  • 자바스크립트의 모든 값(원시 값, 객체, 함수, 배열 등)은 배열의 요소가 될 수 있다.
const apple = fruit[0];
const banana = fruit[1];
  • 배열의 요소는 자신의 위치를 나타내는 0 이상의 정수인 인덱스(index) 를 갖는다.
  • 인덱스는 배열의 요소에 접근할 때 사용한다. 접근할 때에는 대괄호 [ ] 를 사용한다.
console.log(fruit.length); 		// 3
  • 배열은 길이를 나타내는 length 프로퍼티를 갖는다.
console.log(typeof arr);		// object
  • 자바스크립트에 배열이라는 타입이 존재하지 않는다. 배열은 객체 타입이다.

27-2. 자바스크립트의 배열은 객체이다.

  • 위에서 typeof 연산자를 사용해 배열의 타입을 확인하면 object가 출력됐다.
  • 그렇다면 자바스크립트에서 배열은 존재하지 않을까?

27-2-1. 밀집 배열(dense array)

  • 자료구조(data structure)에서 흔히 말하는 배열은 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 것을 말한다.
  • 또한, 배열의 요소는 하나의 데이터 타입으로 통일되어 있으며 서로 인접해있다. 이러한 배열을 밀집 배열(dense array)이라 한다.
  • 밀집 배열은 인덱스를 통해 효율적으로 요소에 접근할 수 있다는 장점이 있지만 정렬되지 않았다면 특정 요소를 발견할 때까지 차례대로 검색해야 하는 단점이 있다.

27-2-2. 희소 배열(sparse array)

  • 자바스크립트의 배열은 밀집 배열과 다른데 배열의 요소가 동일한 크기의 메모리 공간을 갖지 않아도 되며, 연속적으로 이어져 있지 않을 수도 있다.
  • 즉, 자바스크립트의 배열은 일반적인 배열의 동작을 흉내 낸 특수한 객체이다.
const arr = [
  "string",
  1,
  true,
  null,
  undefined,
  NaN,
  [],
  { key1: {}, key2: {} },
];
  • 자바스크립트 배열은 인덱스로 요소에 접근하는 일반적인 배열보다 느리지만 특정 요소를 검색하거나 요소를 삽입할 경우에는 빠르다.
  • 대부분의 모던 자바스크립트 엔진은 일반 배열보다 느릴 수 밖에 없는 구조적인 단점을 보완하기 위해 더 배열처럼 동작하도록 최적화하여 구현했다.

27-3. length 프로퍼티와 희소 배열

  • length 프로퍼티는 요소의 개수, 즉 배열의 길이를 나타내는 0 이상의 정수를 값으로 갖는다.
  • 빈 배열일 경우 값은 0이며, 빈 배열이 아닐 경우 요소 중 가장 큰 인덱스에 1을 더한 것과 같다.
  • length 프로퍼티의 값은 배열에 요소를 추가하거나 삭제하면 자동으로 갱신된다.
  • 그리고 원래의 length 프로퍼티 값보다 작은 숫자 값을 할당하면 배열의 길이가 줄어든다.
const arr = [1, 2, 3, 4, 5];
arr.length = 3;

console.log(arr);

// 결과
[1, 2, 3]
  • 그렇다고 원래의 length 프로퍼티 값보다 큰 숫자 값을 할당해도 배열의 길이가 늘어나지 않는다.
const arr = [1];
arr.length = 3;

console.log(arr.length);
console.log(arr);
console.log(arr[1]);

// 결과
3
(3) [1, 비어 있음 × 2]
undefined
  • 위 출력 결과에서 비어 있음 x 2는 실제로 추가된 배열의 요소가 아니기 때문에 arr[1]과 arr[2]에는 값이 존재하지 않는다.
  • 이처럼 자바스크립트의 배열은 배열의 요소가 연속적으로 위치하지 않고 일부가 비어 있는 희소 배열이다.
const sparse = [, 2, , 4];

console.log(sparse.length);
console.log(sparse);

// 결과
4
(4) [비어 있음, 2, 비어 있음, 4]
  • 일반적인 배열의 length는 배열의 개수 즉, 배열의 길이와 항상 일치한다. 하지만, 희소 배열은 length와 요소의 개수가 항상 일치하지는 않는다.
  • 자바스크립트는 문법적으로 희소 배열을 허용하지만 희소 배열은 사용하지 않는 것이 좋다.
  • 최적화가 잘 되어 있는 모던 자바스크립트 엔진은 요소의 타입이 일치하는 배열을 생성할 때 일반적인 의미의 배열처럼 연속된 메모리 공간을 확보하는 것으로 알려져 있다.

27-4. 배열 생성

27-4-1. 배열 리터럴

  • 가장 일반적인 배열을 생성하는 방법으로 0개 이상의 요소를 쉼표로 구분해 대괄호 [ ] 로 묶는다.
const arr = [1, 2, 3];

27-4-2. Array 생성자 함수

  • Object 생성자 함수를 통해 객체를 생성하듯이 Array 생성자 함수를 통해 배열을 생성할 수 있다.
const arr = new Array(10);
console.log(arr); 		// (10) [비어 있음 × 10]
  • Array 생성자 함수는 전달된 인수의 개수에 따라 다르게 동작하므로 주의가 필요하다.
  • 인수가 하나라면 인수에 해당하는 숫자의 길이만큼 배열을 생성한다.
const arr = new Array(1, 2, 3);
console.log(arr);		// (3) [1, 2, 3]
  • 인수의 개수가 2개 이상이면 인수를 요소로 갖는 배열을 생성한다.

27-4-3. Array.of

  • ES6에 도입된 Array.of 메서드는 전달된 인수를 요소로 갖는 배열을 생성한다.
  • Array 생성자 함수와는 다르게 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
const arr1 = Array.of(1);
const arr2 = Array.of(1, 2, 3);

console.log(arr1);				// [1]
console.log(arr2);				// [1, 2, 3]

27-4-4. Array.from

  • ES6에 도입된 Array.from 메서드는 유사 배열 객체 또는 이터러블 객체를 인수로 전달받아 배열로 변환하여 반환한다.
const arr1 = Array.from({length: 2, 0: 'a', 1: 'b'});
const arr2 = Array.from('hello');

console.log(arr1);				// (2) ['a', 'b']
console.log(arr2);				// (5) ['h', 'e', 'l', 'l', 'o']
  • Array.from을 사용할 때 두 번째 인수로 콜백함수를 전달해 요소를 채울 수 있다.
Arrray.from({ length: 3 }, (_, i) => i);

27-5. 배열 요소의 참조

  • 배열 요소를 참조할 때에는 대괄호 [ ] 표기법을 사용한다.
  • 대괄호 안에는 정수로 평가되는 인덱스를 사용해야 한다.
const arr = [1, 2, 3];

console.log(arr[0]);				// 1	
console.log(arr[1]); 				// 2
console.log(arr[3]);				// undefined

27-6. 배열 요소의 추가와 갱신

  • 객체에 프로퍼티를 동적으로 추가할 수 있는 것처럼 배열에도 요소를 동적으로 추가할 수 있다.
  • 존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가된다. 이때, length 프로퍼티는 자동으로 갱신 된다.
const arr = [0];
arr[1] = 1;

console.log(arr.length);			// 2
  • 이 때 명시적으로 값을 할당하지 않는 요소는 생성되지 않는다.
const arr = [1, 2, 3];
arr[5] = 6;

console.log(arr);					// (6) [1, 2, 3, 비어 있음 × 2, 6]
console.log(arr.length);			// 6

27-7. 배열 요소의 삭제

27-7-1. delete 연산자

  • 배열의 요소를 삭제할 때에는 delete 연산자를 사용하는 방법이 있다.
const arr = [1, 2, 3];
delete arr[1];

console.log(arr);					// (3) [1, 비어 있음, 3]
console.log(arr.length);			// 3
  • 위 예에선 배열 arr에서 프로퍼티 키가 1인 프로퍼티를 삭제한다.
  • 이때, 배열은 희소 배열이 되고 length 프로퍼티값은 변하지 않는다.
  • 희소 배열을 만들지 않기 위해 delete 연산자를 사용하지 않는 것이 좋다.

27-7-2. splice 메서드

  • 희소 배열을 만들지 않으면서 배열의 특정 요소를 완전히 삭제하려면 Array.prototype.splice 메서드를 사용하면 된다.
const arr = [1, 2, 3];
arr.splice(1, 1);

console.log(arr);					// (2) [1, 3]
console.log(arr.length);			// 2

Array.prototype.splice()

  • splice() 메서드는 배열의 기존 요소를 삭제 또는 교체하거나 새 요소를 추가하여 배열의 내용을 변경한다.
  • array.splice(start[, deleteCount[, item1[, item2[, ...]]]])
  • 첫 번째 인수 start는 배열의 변경을 시작할 인덱스로 음수일 경우 배열의 끝에서 시작한다.
  • deleteCount는 배열에서 제거할 요소의 수를 나타낸다.
  • 반환 값은 제거한 요소를 담은 배열을 리턴한다.
const arr = [1, 2, 3];
const spliceArr = arr.splice(1, 2);
console.log(spliceArr);				// [2, 3]
console.log(arr);					// [1]
profile
개발자가 되고 싶은 개발자

0개의 댓글