Language/Javascript

[Javascript] 자바스크립트 표준 객체 - Array 객체와 메소드

재은초 2023. 8. 2. 22:26
반응형

Array 객체란?

  • 자바스크립트에서 배열은 정렬된 값들의 집합으로 정의되며, Array 객체로 다뤄진다.
  • 배열(array)은 1개의 변수에 여러 개의 값을 순차적으로 저장할 때 사용한다. 자바스크립트의 배열은 객체이며 유용한 내장 메소드를 포함하고 있다.
  • 배열은 Array 생성자로 생성된 Array 타입의 객체이며 프로토타입 객체는 Array.prototype이다.

배열과 객체의 차이

  • 배열 리터럴은 객체 리터럴과 달리 프로퍼티명이 없고 각 요소의 값만이 존재한다. 배열은 요소에 접근하기 위해 대괄호 표기법만을 사용하며 대괄호 내에 접근하고자 하는 요소의 인덱스를 넣어준다. 객체는 프로퍼티 값에 접근하기 위해 대괄호 표기법 또는 마침표 표기법을 사용하며 프로퍼티명을 키로 사용한다.
  • 대부분의 프로그래밍 언어에서 배열의 요소들은 모두 같은 데이터 타입이어야 하지만, 자바스크립트 배열은 어떤 데이터 타입의 조합이라도 포함할 수 있다.
  • 두 객체의 근본적 차이는 배열 리터럴 arr의 프로토타입 객체는 Array.prototype이지만 객체 리터럴 obj의 프로토타입 객체는 Object.prototype이라는 것이다.

https://poiemaweb.com/js-array

// 배열
const arr = [
  'zero', 'one', 'two', 'three', 'four',
  'five', 'six', 'seven', 'eight', 'nine'
];

console.log(arr[1]);      // 'one'
console.log(arr.length);  // 10
console.log(typeof arr);  // object


// 객체
const obj = {
  '0': 'zero',  '1': 'one',   '2': 'two',
  '3': 'three', '4': 'four',  '5': 'five',
  '6': 'six',   '7': 'seven', '8': 'eight',
  '9': 'nine'
};
const emptyArr = [];
const emptyObj = {};

console.dir(emptyArr.__proto__);
console.dir(emptyObj.__proto__);

https://poiemaweb.com/js-array

 

배열의 생성

배열 리터럴

  • 0개 이상의 값을 쉼표로 구분하여 대괄호([])로 묶는다. 첫번째 값은 인덱스 ‘0’으로 읽을 수 있다. 존재하지 않는 요소에 접근하면 undefined를 반환한다.
const emptyArr = [];

console.log(emptyArr[1]);       // undefined
console.log(emptyArr.length);   // 0

Array() 생성자 함수

  • 배열은 일반적으로 배열 리터럴 방식으로 생성하지만 배열 리터럴 방식도 결국 내장 함수 Array() 생성자 함수로 배열을 생성하는 것을 단순화시킨 것이다.
  • Array() 생성자 함수는 매개변수의 갯수에 따라 다르게 동작한다. 매개변수가 1개이고 숫자인 경우 매개변수로 전달된 숫자를 length 값으로 가지는 빈 배열을 생성한다. 그 외의 경우 매개변수로 전달된 값들을 요소로 가지는 배열을 생성한다.
const arr = new Array(2);
console.log(arr); // (2) [empty × 2]

const arr = new Array(1, 2, 3);
console.log(arr); // [1, 2, 3]

 

배열 요소의 추가

  • 객체가 동적으로 프로퍼티를 추가할 수 있는 것처럼 배열도 동적으로 요소를 추가할 수 있다. 이때 순서에 맞게 값을 할당할 필요는 없고 인덱스를 사용하여 필요한 위치에 값을 할당한다. 배열의 길이(length)는 마지막 인덱스를 기준으로 산정된다.
  • 값이 할당되지 않은 인덱스 위치의 요소는 생성되지 않는다는 것에 주의하자. 단, 존재하지 않는 요소를 참조하면 undefined가 반환된다.
const arr = [];
console.log(arr[0]); // undefined

arr[1] = 1;
arr[3] = 3;

console.log(arr); // (4) [empty, 1, empty, 3]
console.log(arr.lenth); // 4

 

배열 요소의 삭제

  • 배열은 객체이기 때문에 배열의 요소를 삭제하기 위해 delete 연산자를 사용할 수 있다. 이때 length에는 변함이 없다. 해당 요소를 완전히 삭제하여 length에도 반영되게 하기 위해서는 Array.prototype.splice 메소드를 사용한다.
const numbersArr = ['zero', 'one', 'two', 'three'];

// 요소의 값만 삭제된다
delete numbersArr[2]; // (4) ["zero", "one", empty, "three"]
console.log(numbersArr);

// 요소 값만이 아니라 요소를 완전히 삭제한다
// splice(시작 인덱스, 삭제할 요소수)
numbersArr.splice(2, 1); // (3) ["zero", "one", "three"]
console.log(numbersArr);

 

배열의 순회

  • 객체의 프로퍼티를 순회할 때 for…in 문을 사용하는데 배열 역시 객체이므로 for…in 문을 사용할 수 있다. 그러나 배열은 객체이기 때문에 프로퍼티를 가질 수 있다. for…in 문을 사용하면 배열 요소뿐만 아니라 불필요한 프로퍼티까지 출력될 수 있고 요소들의 순서를 보장하지 않으므로 배열을 순회하는데 적합하지 않다. 따라서 배열의 순회에는 forEach 메소드, for 문, for…of 문을 사용하는 것이 좋다.
const arr = [0, 1, 2, 3];
arr.foo = 10;

for (const key in arr) {
  console.log('key: ' + key, 'value: ' + arr[key]);
}
// key: 0 value: 0
// key: 1 value: 1
// key: 2 value: 2
// key: 3 value: 3
// key: foo value: 10 => 불필요한 프로퍼티까지 출력

arr.forEach((item, index) => console.log(index, item));

for (let i = 0; i < arr.length; i++) {
  console.log(i, arr[i]);
}

for (const item of arr) {
  console.log(item);
}

 

Array 프로퍼티

Array.length

  • length 프로퍼티는 요소의 개수(배열의 길이)를 나타낸다. 배열 인덱스는 32bit 양의 정수로 처리된다. 따라서 length 프로퍼티의 값은 양의 정수이며 232 - 1(4,294,967,296 - 1) 미만이다.
  • 배열 요소의 개수와 length 프로퍼티의 값이 일치하지 않는 배열을 희소 배열(sparse array)이라 한다. 희소 배열은 배열의 요소가 연속적이지 않은 배열을 의미한다. 희소 배열이 아닌 일반 배열은 배열의 요소 개수와 length 프로퍼티의 값이 언제나 일치하지만 희소 배열은 배열의 요소 개수보다 length 프로퍼티의 값이 언제나 크다. 희소 배열은 일반 배열보다 느리며 메모리를 낭비한다.
const arr = [];
console.log(arr.length); // 0

arr[1000] = true;

console.log(arr);        // (1001) [empty × 1000, true]
console.log(arr.length); // 1001
console.log(arr[0]);     // undefined
  • length 프로퍼티의 값은 명시적으로 변경할 수 있다. 만약 length 프로퍼티의 값을 현재보다 작게 변경하면 변경된 length 프로퍼티의 값보다 크거나 같은 인덱스에 해당하는 요소는 모두 삭제된다.
const arr = [ 1, 2, 3, 4, 5 ];

// 배열 길이의 명시적 변경
arr.length = 3;
console.log(arr); // (3) [1, 2, 3]

 

Array 메소드

Array.isArray() 메소드

  • Array.isArray() 메소드는 전달받은 값이 Array 객체인지 아닌지를 검사한다.
Array.isArray([]);          // true
Array.isArray(new Array()); // true
Array.isArray(123);         // false
Array.isArray("Array");     // false
Array.isArray(true);        // false

Array.from() 메소드

  • ES6에서 새롭게 도입된 Array.from 메소드는 유사 배열 객체(array-like object) 또는 이터러블 객체(iterable object)를 변환하여 새로운 배열을 생성한다.
    • 배열과 비슷한 객체(array-like objects): length 프로퍼티와 인덱스 된 요소를 가지고 있는 객체
    • 반복할 수 있는 객체(iterable objects): Map과 Set 객체 및 문자열과 같이 해당 요소를 개별적으로 선택할 수 있는 객체
function arrayFrom() {
    return Array.from(arguments);
}
Array.from(arrayFrom(1, 2, 3));        // [1, 2, 3]

var myMap = new Map([[1, 2], [3, 4]]);
Array.from(myMap);                     // [1, 2, 3, 4]
Array.from("JavaScript");              // [J,a,v,a,S,c,r,i,p,t]

Array.of() 메소드

  • ES6에서 새롭게 도입된 Array.of 메소드는 전달된 인수를 요소로 갖는 배열을 생성한다.
  • 이때 Array.of() 메소드와 Array 객체 생성자의 차이는 정수로 전달된 인수 처리 방식에 있다. Array.of는 Array 생성자 함수와 다르게 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
new Array(10); // [,,,,,,,,,] -> 10개의 배열 요소를 가지는 빈 배열을 생성
Array.of(10);  // [10] -> 한 개(숫자 10)의 배열 요소를 가지는 배열을 생성

 

Array.prototype 메소드

원본 배열을 변경하는 Array.prototype 메소드

push() 메소드

  • 인수로 전달받은 모든 값을 원본 배열의 마지막에 요소로 추가하고 변경된 length 값을 반환한다. push 메소드는 원본 배열을 직접 변경한다.
var arr = [1, true, "JavaScript"];
arr.length;               // 3

arr.push("자바스크립트");
arr.length;               // 4
arr;                      // [1,true,JavaScript,자바스크립트]

arr.push(2, "거짓");
arr.length;               // 6
arr;                      // [1,true,JavaScript,자바스크립트,2,거짓]

pop() 메소드

  • pop() 메소드는 배열의 가장 마지막 요소를 제거하고 그 제거된 요소를 반환하므로, 실행할 때마다 배열의 길이는 1씩 줄어든다.
  • 원본 배열이 빈 배열이면 undefined를 반환한다. pop 메소드는 원본 배열을 직접 변경한다.
var arr = [1, true, "JavaScript", "자바스크립트"];
arr.length;  // 4

arr.pop();   // 자바스크립트
arr.length;  // 3

arr.pop();   // JavaScript
arr.length); // 2
arr;         // [1,true]

shift() 메소드

  • shift() 메소드는 배열의 가장 첫 요소를 제거하고 그 제거된 요소를 반환하며, 배열의 길이가 1씩 줄어든다.
  • 만약 빈 배열일 경우 undefined를 반환한다. shift 메소드는 대상 배열 자체를 변경한다.
var arr = [1, true, "JavaScript", "자바스크립트"];
arr.length;  // 4
arr.shift(); // 1

arr.length;  // 3
arr.shift(); // true

arr.length;  // 2
arr;         // [JavaScript,자바스크립트]

unshift() 메소드

  • unshift() 메소드는 하나 이상의 요소를 배열의 가장 앞에 추가하며, 원본 배열은 추가한 요소의 수만큼 길이가 늘어난다.
var arr = [1, true, "JavaScript"];
arr.length;                  // 3
arr.unshift("자바스크립트");

arr.length;                  // 4
arr;                         // [자바스크립트,1,true,JavaScript]

arr.unshift(2, "거짓");
arr.length;                  // 6
arr;                         // [2,거짓,자바스크립트,1,true,JavaScript]

reverse() 메소드

  • reverse() 메소드는 배열 요소의 순서를 전부 반대로 교체한다. 
var arr = [1, true, "JavaScript", "자바스크립트"];
arr.reverse();             // [자바스크립트,JavaScript,true,1]]

sort() 메소드

  • sort() 메소드는 해당 배열의 배열 요소들을 알파벳 순서에 따라 정렬하는데, 배열 요소를 모두 문자열로 보고 정렬하므로 숫자나 불리언과 같은 타입의 요소들은 잘못 정렬될 수도 있다.
var strArr = ["로마", "나라", "감자", "다람쥐"]; // 한글은 ㄱ,ㄴ,ㄷ 순으로 정렬
var numArr = [10, 21, 1, 2, 3];             // 숫자는 각 자릿수별로 비교 후 정렬
strArr.sort();                              // [감자,나라,다람쥐,로마]
numArr.sort();                              // [1,10,2,21,3]

splice() 메소드

  • splice() 메소드는 기존의 배열 요소를 제거하거나 새로운 배열 요소를 추가하여 배열의 내용을 변경하는데, 배열에서 제거된 요소를 배열의 형태로 반환하며 아무 요소도 제거되지 않았으면 빈 배열을 반환한다.
  • 첫 번째 인수는 새로운 요소가 삽입될 위치의 인덱스이고, 두 번째 인수는 제거할 요소의 개수며, 그 이후의 인수들은 모두 배열 요소로서 지정된 인덱스부터 차례대로 삽입된다.
var arr = [1, true, "JavaScript", "자바스크립트"];

// 인덱스 1의 요소부터 2개의 요소를 제거한 후, false와 "C언어"를 그 자리에 삽입
var removedElement = arr.splice(1, 2, false, "C언어");
arr;            // [1,false,C언어,자바스크립트]
removedElement; // [true,JavaScript]

원본 배열은 변경하지 않고 참조만 하는 메소드

indexOf() 메소드

  • indexOf() 메소드는 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스를 반환한다. 
  • 중복되는 요소가 있으면 첫번째 인덱스를 반환하고 해당하는 요소가 없으면 -1을 반환한다.
const arr = [1, 2, 2, 3];

// 배열 arr에서 요소 2를 검색하여 첫번째 인덱스를 반환
arr.indexOf(2);    // -> 1
// 배열 arr에서 요소 4가 없으므로 -1을 반환
arr.indexOf(4);    // -1
// 두번째 인수는 검색을 시작할 인덱스이다. 두번째 인수를 생략하면 처음부터 검색한다.
arr.indexOf(2, 2); // 2
const foods = ['apple', 'banana', 'orange'];

// foods 배열에 'orange' 요소가 존재하는지 확인
if (foods.indexOf('orange') === -1) {
  // foods 배열에 'orange' 요소가 존재하지 않으면 'orange' 요소를 추가
  foods.push('orange');
}

console.log(foods); // ["apple", "banana", "orange"]

join() 메소드

  • 원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 값인 구분자(separator)로 연결한 문자열을 반환한다. 구분자(separator)는 생략 가능하며 기본 구분자는 ,이다.
var arr = [1, true, "JavaScript"];
arr.join();      // 1,true,JavaScript
arr.join(' + '); // 1 + true + JavaScript
arr.join(' ');   // 1 true JavaScript
arr.join('');    // 1trueJavaScript

slice() 메소드

  • 인자로 지정된 배열의 부분을 복사하여 반환한다. 원본 배열은 변경되지 않는다.
  • 첫번째 매개변수 start에 해당하는 인덱스를 갖는 요소부터 매개변수 end에 해당하는 인덱스를 가진 요소 전까지 복사된다.
var arr = [1, true, "JavaScript", "자바스크립트"];
arr.slice(1, 3); // [true,JavaScript]
arr.slice(1);    // [true,JavaScript,자바스크립트 ]

concat() 메소드

  • 인수로 전달된 값들(배열 또는 값)을 원본 배열의 마지막 요소로 추가한 새로운 배열을 반환한다. 인수로 전달한 값이 배열인 경우, 배열을 해체하여 새로운 배열의 요소로 추가한다. 원본 배열은 변경되지 않는다.
var arr = [1, true, "JavaScript"];

arr.concat([2, false, "문자열"]); // [1,true,JavaScript,2,false,문자열]
arr.concat([2], [3, 4]);        // [1,true,JavaScript,2,3,4] 2개 이상의 배열도 한 번에 합칠 수 있음
arr.concat("다섯", [6, 7]);      // [1,true,JavaScript,다섯,6,7] 값과 배열도 한 번에 합칠 수 있음

toString() 메소드

  • toString() 메소드는 해당 배열의 모든 요소를 하나의 문자열로 반환하는데, 배열 요소의 사이에는 자동으로 쉼표 , 가 삽입된다.
var arr = [1, true, "JavaScript"];
arr.toString(); // '1,true,JavaScript'

원본 배열을 반복적으로 참조하는 메소드

forEach() 메소드

  • forEach() 메소드는 해당 배열의 모든 요소에 대하여 반복적으로 명시된 콜백 함수를 실행한다.
var arr = [1, true, "JavaScript"];

function printArr(value, index, array) {
    document.write("arr[" + index + "] = " + value + "<br>");
}

arr.forEach(printArr); // 배열 arr의 각 요소마다 printArr() 함수가 호출

map() 메소드

  • map() 메소드는 해당 배열의 모든 요소에 대하여 반복적으로 명시된 콜백 함수를 실행한 후, 그 실행 결과를 새로운 배열에 담아 반환한다.
var arr = [1, -2, 3, -4];

// 배열 arr의 각 요소마다 Math.abs() 함수가 호출되고 그 결괏값이 배열로 저장
var absoluteValues = arr.map(Math.abs);
absoluteValues;                          // [1,2,3,4]

filter() 메소드

  • filter() 메소드는 해당 배열의 모든 요소에 대하여 반복적으로 명시된 콜백 함수를 실행한 후, 그 결괏값이 true인 요소들만을 새로운 배열에 담아 반환한다.
var arr = [-10, 5, 100, -20, 40];

function compareValue(value) {
    return value < 10;
}

var lessTen = arr.filter(compareValue);
lessTen; // [-10,5,-20]

every() 메소드

  • every() 메소드는 해당 배열의 모든 요소에 대하여 반복적으로 명시된 콜백 함수를 실행한 후, 그 결괏값이 모두 true일 때에만 true를 반환한다.
var arr = [-10, 5, -20, 4];

function compareValue(value) {
    return value < 10;           // 배열의 모든 요소가 10보다 작음
}

arr.every(compareValue);         // true

some() 메소드

  • some() 메소드는 해당 배열의 모든 요소에 대하여 반복적으로 명시된 콜백 함수를 실행한 후, 그 결괏값이 하나라도 true이면 true를 반환한다.
var arr = [10, 25, -20, 14];

function compareValue(value) {
    return value < 10;          // 배열 요소 중 -20만이 10보다 작음
}

arr.some(compareValue);         // true

reduce() 메소드

  • reduce() 메소드는 해당 배열의 모든 요소를 하나의 값으로 줄이기 위해, 두 개의 인수를 전달받는 콜백 함수를 실행한다.
  • 이때 명시된 콜백 함수에 배열의 첫 번째 요소와 두 번째 요소를 인수로 전달하고 실행하며 그 결과 반환된 결괏값과 세 번째 요소를 다시 인수로 전달하고 실행하는데, 이러한 동작을 반복하여 모든 배열 요소를 인수로 전달하고 마지막으로 반환된 결괏값을 반환한다.
var arr = [1, 2, 3, 4, 5];

function sumOfValues(x, y) {
    return x - y;
}

arr.reduce(sumOfValues);           // 1 - 2 - 3 - 4 - 5 = -13

reduceRight() 메소드

  • reduceRight() 메소드는 reduce() 메소드와 같은 방식으로 실행되며, 배열의 마지막 요소부터 줄이기 시작한다.
var arr = [1, 2, 3, 4, 5];

function sumOfValues(x, y) {
    return x - y;
}

arr.reduceRight(sumOfValues);        // 5 - 4 - 3 - 2 - 1 = -5

entries() 메소드

  • entries() 메소드는 배열 요소별로 키(key)와 값(value)의 한 쌍으로 이루어진 새로운 배열 반복자 객체(Array Iterator Object)를 배열 형태로 반환하며, 이때 키에는 인덱스가 저장되며 값에는 배열 요소의 값이 저장된다.
  • for / of 문은 익스플로러에서 지원하지 않는다.
var arr = [1, true, "JavaScript"];
var arrEntries = arr.entries();

for (var entry of arrEntries) {
    document.write(entry + "<br>");    // 배열 인덱스별로 키와 값의 한 쌍을 출력
}

 

Reference

반응형