[자바스크립트 비기너] 7. Array 오브젝트 ES3/ES5 기준

Speedwell🍀·2022년 1월 31일
0

Array 오브젝트 (ES3 기준)

Array 오브젝트 개요

  • 빌트인 오브젝트

  • Array 형태

    • [123, "ABC", "가나다"]
  • 배열 엘리먼트

    • 123, "ABC" 각각을 엘리먼트 또는 요소라고 부름
    • 2의 32승 (4,294,967,296) - 1개
  • 인덱스

    • 엘리먼트 위치를 인덱스라고 부름
    • 왼쪽부터 0번 인덱스, 1번 인덱스
  • 배열 특징

    • 엘리먼트 작성이 순서를 갖고 있음
    • 배열 전체를 작성한 순서로 읽거나
    • 인덱스로 값을 추출할 수 있음

배열 생성 방법

  • new Array()로 생성

    • var book = new Array();
  • Array()로 생성

    • var book = Array();
  • 대괄호로 생성

    • var book = [];
    • 일반적으로 이 형태를 사용

엘리먼트 작성 방법

  • var book = ["책1", '책2'];

  • 대괄호 안에 콤마로 구분하여 다수 작성 가능

  • String 타입은 큰따옴표, 작은따옴표 모두 가능

  • JS의 모든 타입의 값, 오브젝트 사용 가능

  • 값을 작성하지 않고 콤마만 작성하면 undefined가 설정됨


배열 차원

1차원 배열

  • 대괄호 하나에 엘리먼트 작성
  • [12, 34, 56] 형태
var list = [12, 34, 56];
for (var k = 0; k < list.length; k++) {
	log(list[k]);
};

// 12
// 34
// 56

2차원 배열

  • 배열 안에 1차원 배열을 작성
  • [[12, 34, 56]]
var list = [[12, 34, 56]];
for (var k = 0; k < list.length; k++){
	var one = list[k];
    for (var m = 0; m < one.length; m++){
		log(one[m]);
	};
};

// 12
// 34
// 56

3차원 배열

  • 배열 안에 2차원 배열을 작성
  • [[[12, 34, 56]]]
var list = [[[12, 34, 56]]];
for (var k = 0; k < list.length; k++){
	var one = list[k];
    for (var m = 0; m < one.length; m++){
    	var two = one[m];
        for (var p = 0; p < two.length; p++){
			log(two[p]);
        };
	};
};

// 12
// 34
// 56

Array 인스턴스 생성

new Array()

  • Array 인스턴스 생성, 반환

  • 배열 생성 기준

    • 파라미터에 따라 배열 생성 기준이 다름
    • 파라미터를 작성하지 않으면 빈 배열
    • 작성한 순서로 엘리먼트에 설정
    • new Array(3)처럼 파라미터에 숫자를 작성하면 3개의 엘리먼스 생성
var obj = new Array(); 
log(typeof obj); // new Array()로 생성한 인스턴스 타입은 object
log(obj.length);

// object
// 0
var one = new Array(10, 20);
log(one);
var two = new Array([30, 40]);
log(two);

// [10, 20]
// [[30, 40]]
var obj = new Array(3);
log(obj);

// [undefined, undefined, undefined]

Array()

  • Array 인스턴스 생성, 반환

    • new Array()와 생성 방법 및 기능 같음
  • 인스턴스 생성 논리

    • new Array()는 new 연산자에서 생성자 함수를 호출하여 인스턴스 생성
    • Array()는 직접 생성자 함수를 호출하여 인스턴스 생성

length 프로퍼티

  • 배열 [1, 2, 3]에서

    • length 값은 3
    • Array 오브젝트에 {length: 3} 형태로 설정
  • 열거/삭제는 할 수 없지만, 변경은 가능

  • length 값을 변경하려면 배열의 엘리먼트 수가 변경됨

var value = [1, 2, 3];
value.length = 5;
log(value);

// [1, 2, 3, undefined, undefined]
var value = [1, 2, 3];
value.length = 2; // 뒤의 엘리먼트가 삭제됨
log(value);

// [1, 2]

엘리먼트 추가

  • 배열에 엘리먼트를 추가하는 방법
    • 삽입할 위치에 인덱스 지정
    • 표현식으로 인덱스 지정
var value = [1, 2];
value[4] = 5;
log(value);

// [1, 2, undefined, undefined, 5]
var value = [1, 2];
value[value.length + 2] = 5;
log(value);

// [1, 2, undefined, undefined, 5]

delete 연산자

  • var 변수는 삭제 불가

  • 글로벌 변수는 삭제 가능

  • {name: value} 삭제 방법

    • 삭제할 프로퍼티 이름 작성
    • ES5에서 삭제 불가 설정 가능
  • 인덱스로 배열의 엘리먼트 삭제

var value = 123;
log(delete value); // var 변수 삭제 불가능 => 삭제 실패로 처리하여 false 반환

// false
value = "글로벌 변수"; 
log(delete value); // var키워드 사용하지 않은 글로벌 변수는 삭제 가능 => 삭제해서 true 반환

try {
	log(value); // value 없어서 에러
} catch(e){
	log("존재하지 않음");
};

// true
// 존재하지 않음
var book = {title: "책"}; 
log(delete book.title); // 오브젝트이름.프로퍼티이름 형태로 작성
log(book.title); // 오브젝트에 프로퍼티 이름 없으면 undefined 반환

// true
// undefined
var book = {title: "책"}; 
log(delete book);
// var 변수에 오브젝트 할당하면 오브젝트 전체를 삭제 불가능
// ==> var 키워드를 사용해야 하는 또 하나의 목적

sports = {item: "축구"};
log(delete sports);

// false
// true
var value = [1, 2, 3, 4];
log(delete value[1]);
log(value.length); // length 줄지 않고 그대로 - 배열 처리 메커니즘 때문

// true
// 4

배열 엘리먼트 삭제 메커니즘

  • 삭제된 인덱스에 undefined 설정
    • 앞으로 하나씩 당겨서 엘리먼트를 이동하면 처리 시간이 걸리기 때문
    • 배열을 읽을 때 제외시켜야 함
var value = [1, 2, 3, 4];
delete value[1];
log(value);

for (var k = 0; k < value.length; k++){
	log(value[k]);
};

// [1, undefined, 3, 4]
// 1
// undefined
// 3
// 4

엘리먼트 삽입, 첨부

unshift()

  • 0번 인덱스에 파라미터 값 삽입
  • 배열에 있던 엘리먼트는 뒤로 이동
var value = [1. 2];
value.unshift(345, 67);
log(value);

// [345, 67, 1, 2]

push()

  • 배열 끝에 파라미터 값을 첨부
var value = [1. 2];
value.push(345, 67);
log(value);

// [1, 2, 345, 67]

concat()

  • 배열에 파라미터 값을 연결하여 반환

  • 파라미터가 1차원 배열이면 값만 반영

var value = [1, 2];
var result = value.concat(3, 4);
log(result);

// [1, 2, 3, 4]
var value = [1, 2];
var result = value.concat([3], [4]);
log(result);

// [1, 2, 3, 4]

엘리먼트 복사

slice()

  • 배열의 일부를 복사하여 배열로 반환
    • 첫 번째 파라미터 인덱스부터 두 번째 인덱스 직전까지
var origin = [1, 2, 3, 4, 5];
var result = origin.slice(1, 3);
log(result);
log(origin);

// [2, 3]
// [1, 2, 3, 4, 5]
  • true, false를 숫자로 변환
var value = [1, 2, 3, 4, 5];
log(value.slice(true, 3));
log(value.slice(false, 3));

// [2, 3]
// [1, 2, 3]
  • 첫 번째 파라미터만 작성
log([1, 2, 3, 4, 5].slice(2)); // 2~끝

// [3, 4, 5]
  • 첫 번째 파라미터 값이 클 때
log([1, 2, 3, 4, 5].slice(4, 3));

// []
  • 파라미터에 음수 작성
var value = [1, 2, 3, 4, 5];
log(value.slice(-4, -2)); // 파라미터 값이 음수면 length 값을 더함 -4+5=1, -2+5=3 ==> slice(1, 3)

// [2, 3]

엘리먼트 값을 문자열로 변환

join()

  • 엘리먼트와 분리자를 하나씩 결합하여 문자열로 연결

    • [0] 인덱스, 분리자, [1] 인덱스, 분리자
  • 마지막 엘리먼트는 분리자를 연결하지 않음

var value = [1, 2, 3];
var result = value.join("##");
log(result);
log(typeof result);

// 1##2##3
// string
  • 파라미터를 작성하지 않으면 콤마로 분리
var value = [1, 2, 3];
var result = value.join();
log(result);

// 1,2,3
  • 파라미터에 빈 문자열 작성
    • 엘리먼트 값만 연결하여 반환
    • 사용 빈도수 높음
    • 데이터로 HTML의 마크업을 만들어 한 번에 표시할 때 사용 (e.g. <table>)
var value = [1, 2, 3];
var result = value.join("");
log(result);

// 123

toString()

  • 배열의 엘리먼트 값을 문자열로 연결
    • 콤마로 엘리먼트를 구분
var result = ["A", "B", "C"].toString();
log(result);
log([["가"]. ["다"]].toString()); // 2차원 배열의 각 엘리먼트 값을 1차원 배열로 펼치고, 다시 1차원을 문자열로 연결

// A,B,C
// 가,다

toLocalString()

  • 엘리먼트 값을 지역화 문자로 변환
    • 문자열을 콤마로 연결하여 반환
var value = [12, 34, 56];
log(value.toLocalString(
	"zh-Hans-CN-u-nu-hanidec"));
    
// 一二.三四,五六

엘리먼트 삭제

shift()

  • 배열의 첫 번째 엘리먼트 삭제

  • 삭제한 엘리먼트 값이 undefined로 남지 않고 완전히 삭제됨

    • length 값이 하나 줄어듦
var value = [1, 2, 34];
log(value.shift());
log(value);

// 1
// [2, 34]
  • 빈 배열이면 undefined 반환 됨
var result = [].shift();
log(result);

// undefined

pop()

  • 배열의 마지막 엘리먼트 삭제

  • 삭제한 엘리먼트 값이 undefined로 남지 않고 완전히 삭제됨

    • length 값이 하나 줄어듦
var value = [1, 2, 34];
log(value.pop());
log(value);

// 34
// [1, 2]
  • 빈 배열이면 undefined 반환
var result = [].pop();
log(result);

// undefined

splice()

  • 엘리먼트를 삭제하고 삭제한 엘리먼트 반환
var value = [1, 2, 3, 4, 5];
log(value.splice(1, 3)); // 1번 인덱스부터 엘리먼트 3개 삭제. 뒤의 엘리먼트가 앞으로 당겨짐
log(value);

// [2, 3, 4]
// [1, 5]
  • 삭제한 위치에 세 번째 파라미터 삽입
var value = [1, 2, 3, 4, 5];
log(value.splice(1, 3, "A", "B"));
log(value);

// [2, 3, 4]
// [1, A, B, 5]
  • 파라미터를 작성하지 않으면?
    • 삭제하지 않음 ➡ 삭제한 것이 없으므로 빈 배열 반환
var value = [1, 2, 3, 4, 5];
log(value.splice()); 
log(value);

// []
// [1, 2, 3, 4, 5]

정렬

sort()

  • 엘리먼트 값을 승순으로 정렬

  • 정렬 기준은 엘리먼트 값의 Unicode

    • 코드 포인트가 작으면 앞에 오고 크면 뒤에 옴
var value = [4, 2, 3, 1];
log(value.sort());

// [1, 2, 3, 4]
var value = ["A1", "A01", "B2", "B02"];
log(value.sort());

// [A01, A1, B02, B2]
  • 주의 : sort 대상 배열도 정렬됨
    • sort 대상 배열 정렬되면 안되는 경우엔 사전에 복사해둬야 함
var value = [4, 2, 3, 1];
log(value.sort());
log(value);

// [1, 2, 3, 4]
// [1, 2, 3, 4]
  • 값이 undefined이면 끝으로 이동
var value = [, , 1, 2];
log(value.sort());

// [1, 2, undefined, undefined]

sort()와 Unicode

  • 숫자에 해당하는 Unicode의 code point로 정렬
    • 이를 해결하려면 sort()의 파라미터에 함수를 작성하고 함수에서 정렬해야 함
var value = [101, 26, 7, 1234];
log(value.sort());

// [101, 1234, 26, 7]

sort() : sort 알고리즘

var value = [101, 26, 7, 1234];
value.sort(function(one, two){
	return one - two;
});
log(value);

// [7, 26, 101, 1234]
  1. sort() 파라미터의 function(){}을 호출하면서 101과 26을 파라미터 값으로 넘김. 101이 one, 26이 two에 설정됨.

  2. one(101) - two(26)의 결과는 양수이며 이 값을 반환

  3. 이때, 0보다 큰 값이 반환되면 배열에서 값의 위치를 바꿈. 즉, [26, 101, 7, 1234]

  4. 다시 콜백 함수를 호출하면서 101과 7을 넘겨줌. one(101) - two(7)의 결과는 양수이며 0보다 큰 값을 반환

  5. 반환 값이 0보다 크므로 배열에서 값의 위치를 바꿈. 즉, [26, 7, 101, 1234]

  6. 다시 함수 호출, 101과 1234 넘겨줌. one(101) - two(1234)의 결과는 음수이며 0보다 작은 값 반환

  7. 반환 값이 0보다 작거나 같으면 배열에서 값의 위치 바꾸지 않음. 즉, [26, 7, 101, 1234]

  8. 다시 처음으로 돌아가 바뀌는 것이 없을 때까지 배열의 엘리먼트 위치를 조정


reverse()

  • 배열의 엘리먼트 위치를 역순으로 바꿈
    • 엘리먼트 값이 아닌 인덱스 기준
    • 대상 배열도 바뀜
var value = [1, 3, 7, 5];
log(value.reverse());

// [5, 7, 3, 1]

Array 오브젝트(ES5 기준)

isArray()

  • 체크 대상이 배열이면 true, 아니면 false

  • isArray()는 함수

log(Array.isArray([1, 2])); // isArray()는 함수이므로 Array.isArray() 형태로 호출
log(Array.isArray(123));

// true
// false
  • isArray() 함수가 필요한 이유
    • typeof 연산자로 데이터 타입을 구하면 모두 object이므로 배열 여부 체크 불가
    • [1, 2]는 Array.isArray() 사용
    • null은 Object.is() 사용
log(typeof {a: 1});
log(typeof [1, 2]);
log(typeof null);

// object
// object
// object

index 처리 메소드

indexOf()

  • 파라미터 값과 같은 엘리먼트의 인덱스 반환

    • 왼쪽에서 오른쪽으로 검색
    • 값이 같은 엘리먼트가 있으면 검색 종료
    • 데이터 타입까지 체크
  • 두 번째 파라미터의 인덱스부터 검색

  • String과 Array의 indexOf() 차이

var value = [1, 2, 5, 4, 5]; // number 타입
log(value.indexOf(5));
log(value.indexOf("5")); // 타입이 달라서 -1 반환
log(value.indexOf(5, 3)); // 3은 검색 시작 인덱스

// 2
// -1
// 4

log("ABCBC".indexOf("C", -2)); // String 오브젝트는 음수는 0으로 간주
var list = ["A", "B", "C", "B", "C"];
log(list.indexOf("C", -2)); // Array 오브젝트는 음수에 length 더해서 시작 인덱스

// 2
// 4

lastIndexOf()

  • 파라미터 값과 같은 엘리먼트의 마지막 인덱스 반환
var value = [1, 2, 5, 2, 5];
log(value.lastIndexOf(5));

// 4

콜백 함수를 가진 Array 메소드 (키워드: 시맨틱, 독립성)

forEach()

  • 배열의 엘리먼트를 하나씩 읽어 가면서 콜백 함수 호출

  • 콜백 함수 파라미터

    • 엘리먼트 값, 인덱스, 배열 전체
var list = ["A", "B", "C"];
list.forEach(function(el, index, all){
	log(el + ":" + index + ":" + all);
});

// A:0:A,B,C
// B:1:A,B,C
// C:2:A,B,C
  • break, continue 사용 불가. throw는 사용 가능

  • 콜백 함수 분리(독립성)

    • 위의 방법보다 이 방법이 더 좋음 (코드 중복 피하기 위해)
var list = ["A", "B", "C"];
var fn = function(el, index, all){
	log(el + ":" + index + ":" + all);
};

list.forEach(fn);

// A:0:A,B,C
// B:1:A,B,C
// C:2:A,B,C
  • this로 오브젝트 참조
    • 콜백 함수의 완전한 독립성을 보장
 var list = [1, 2];
 var fn = function(el, index, all){
 	log(el + this.ten);
};

list.forEach(fn, {ten: 10});

// 11
// 12
  • forEach()를 시작할 때 반복 범위 설정

  • 엘리먼트를 추가하더라도 처리하지 않음

var list = [1, 2, 3];
var fn = function(el, index, all){
	if (index === 0){
    	list.push("AB"); // 반복 도중 배열에 엘리먼트 추가하면 처리하지 않음
	};
    log(el);
};
list.forEach(fn);

// 1
// 2
// 3
  • 현재 인덱스보다 큰 인덱스의 값을 변경하면 변경된 값을 사용
    • 현재 인덱스보다 작은 인덱스 값을 변경하면 처리하지 않음
var list = [1, 2, 3];
var fn = function(el, index, all){
	if (index === 0){
    	list[2] = 345;
	};
    log(el);
};
list.forEach(fn);

// 1
// 2
// 345
  • 현재 인덱스보다 큰 인덱스의 엘리먼트를 삭제하면 배열에서 삭제되므로 반복에서 제외됨
    • 추가는 처리하지 않지만, 삭제는 반영
var list = [1, 2, 3];
var fn = function(el, index, all){
	if (index === 0){
    	delete list[2];
	};
    log(el);
};
list.forEach(fn);

// 1
// 2

for()와 forEach()

  • forEach()는 시맨틱 접근

    • 처음부터 끝까지 반복한다는 시맨틱
    • 반복 중간에 끝나지 않는다는 시맨틱
    • 시맨틱으로 소스 코드의 가독성 향상
  • for()는 함수 코드를 읽어야 알 수 있음

    • break, continue
  • forEach()는 반복만 하며

    • 콜백 함수에서 기능 처리, this 사용 가능
  • forEach()는 인덱스 0부터 시작

    • for()와 같이 인덱스 증가 값을 조정할 수 없음
    • 뒤에서 앞으로 읽을 수도 없음. 이것도 시맨틱 접근

true, false 반환하는 메소드

every()

  • forEach()처럼 시맨틱 접근

  • 배열의 엘리먼트를 하나씩 읽어가면서

    • false를 반환할 때까지 콜백 함수 호출
    • 즉, false가 반환되면 반복 종료
    • false를 반환하지 않으면 true 반환
  • false가 되는 조건이 배열의 앞에 있을 때 효율성 높음

var value = [20, 10, 30, 40];
var fn = function(el, index, all){
	log(el);
    return el > 15;
};
var result = value.every(fn);
log("결과:", result);

// 20
// 10
// 결과:false

some()

  • every()처럼 시맨틱 접근

  • 단, true를 반환할 때까지 콜백 함수 호출

    • 즉, true가 반환되면 반복 자동 종료
    • true를 반환하지 않으면 false 반환
  • true가 되는 조건이 배열의 앞에 있을 때 효율성 높음

var value = [20, 10, 30, 40];
var fn = function(el, index, all){
	log(el);
    return el > 15;
};
var result = value.some(fn);
log("결과:", result);

// 10
// 20
// 결과:true

filter()

  • forEach()처럼 시맨틱 접근

  • 배열의 엘리먼트를 하나씩 읽어가면서

    • 콜백 함수에서 true를 반환하면 현재 읽은 엘리먼트를 반환
  • 조건에 맞는 엘리먼트를 추려낼 때 유용

var value = [10, 20, 30, 40];
var fn = function(el, index, all){
	return el > 15;
};
var result = value.filter(fn);
log(result);

// [20, 30, 40]

map()

  • forEach()처럼 시맨틱 접근

  • 파라미터: 콜백 함수, this로 참조할 오브젝트

  • 배열의 엘리먼트를 하나씩 읽어가면서

    • 콜백 함수에서 반환한 값을 새로운 배열에 첨부하여 반환
var value = [10, 20, 30];
var fn = function(el, index, all){
	return el + this.add;
};

var point = {add: 100};
var result = value.map(fn, point);
log(result);

[110, 120, 130]

반환 값을 파라미터 값으로 사용

reduce()

  • forEach()처럼 시맨틱 접근

  • 배열 끝까지 콜백 함수 호출

    • 파라미터 작성 여부에 따라 처리가 다름
  • 콜백 함수만 작성한 경우

    • 즉, 파라미터를 하나만 작성
  • 처음 콜백 함수를 호출할 때

    • 인덱스 [0]의 값을 직접 값에 설정
    • 인덱스 [1]의 값을 현재 값에 설정
    • 인덱스에 1을 설정
  • 두 번째로 콜백 함수를 호출할 때

    • 콜백 함수에서 반환된 값을 직전 값에 설정
    • 인덱스 [2]의 값을 현재 값에 설정
var value = [1, 3, 5, 7];
var fn = function(prev, curr, index, all){
	log(prev + "," + curr); // 4번이 아닌 3번 반복한 것은 처음 시작 인덱스가 1
    return prev + curr;
};
var result = value.reduce(fn);
log("결과:", result);

// 1,3
// 4,5
// 9,7
// 결과:16

  • 두 번째 파라미터를 작성한 경우

  • 처음 콜백 함수를 호출할 때

    • 두 번째 파라미터 값을 직전 값에 설정
    • 인덱스 [0]의 값을 현재 값에 설정
    • 인덱스에 0을 설정
  • 두 번째로 콜백 함수를 호출할 때

    • 콜백 함수에서 반환된 값을 직전 값에 설정
    • 인덱스 [1]의 값을 현재 값에 설정
var value = [1, 3, 5];
var fn = function(prev, curr, index, all){
	log(prev + "," + curr);
    return prev + curr;
};
var result = value.reduce(fn, 7); // 처음 콜백 함수 호출할 때 prev에 7 설정
log("반환:", result);

// 7,1
// 8,3
// 11,5
// 반환:16

reduceRight()

  • reduce()와 처리 방법 같음

  • 배열 끝에서 앞으로 하나씩 읽어가면서

    • 콜백 함수에서 반환한 값을 반환
var value = [1, 3, 5, 7];
var fn = function(prev, curr, index, all){
	log(prev + "," + curr);
    return prev + curr;
};
var result = value.reduceRight(fn);
log("반환:", result);

// 7,5
// 12,3
// 15,1
// 반환:16

0개의 댓글