회고록 블로그
[공부 필기] JavaScript 문법 공부 25일차 (2) 본문
※ 필자는 초초초보자입니다.
※ 틀린 내용에 대한 피드백은 언제든지 환영합니다.
공부하고 있는 자료 : modern JavaScript tutorial
https://ko.javascript.info/array
✅ 배열
- 객체는 기본적으로 순서를 고려하지 않고 만들어진 자료구조이므로
기존의 프로퍼티 사이에 새로운 프로퍼티를 끼워넣는 등이 불가능하다.
- 이럴 때 사용하는 자료구조가 배열이다.
✅ 배열 선언
let arr1 = new Array();
let arr2 = [];
- length를 사용하면 배열에 담긴 요소가 몇 개인지 알아낼 수 있다.
- alert을 사용하면 전체 요소를 출력할 수도 잇다.
- 배열 요소의 자료형엔 제약이 없다.
📌 trailing 쉼표
- 객체처럼 마지막 요소는 쉼표로 끝내도 된다.
let arr1 = [
"apple",
"orange",
"pine apple",
];
✅ pop과 push , shift와 unshift
- 큐(queue) : 배열을 사용해 만들 수 있는 대표적인 자료구조
► 순서가 있는 컬렉션을 저장할 때도 사용한다
- 큐에서 사용하는 주요 연산은 다음과 같다.
► push : 맨 끝에 요소를 넣어라(?)
► shift : 제일 앞 요소를 꺼내고 남아있는 요소들을 앞으로 밀어라(?)
- 배열은 큐를 구현하거나, 스택을 구현할 때 자주 사용된다.
► 배열에는 요소를 넣고 꺼내는 기능을 해주는 내장 메서드가 있다. push와 pop, shift와 unshift이다.
► 배열로 스택을 구현할 때는 push가 요소를 스택 끝에 집어넣고, pop이 스택 끝 요소를 추출한다.
※ 스택과 큐를 컴퓨터 과학 분야에선 데큐(deque, Double Ended Queue)라고 한다.
📌 뒤의 요소를 지지고 볶을 때
- push : 배열의 요소를 끝에 집어넣는다
- pop : 끝 요소를 추출한다. (배열에서는 제거한다)
// pop
let grade = ["1학년", "2학년", "3학년"];
alert(grade.pop()); // 끝의 요소(=3학년) 빼옴
alert(grade); // 끝의 요소(=3학년)는 배열에서 제거된다.
// push
let grade = ["1학년", "2학년", "3학년"];
grade.push("4학년"); //끝에 요소 추가(=4학년 추가)
alert(grade); // 요소 추가돼서 총 4개 요소가 출력됨
📌 앞의 요소를 지지고 볶을 때
- unshift : 배열의 앞에 요소를 추가한다.
- shift : 배열의 앞 요소를 추출한다. (해당 요소는 배열에서 제거된다)
let grade = ["1학년", "2학년", "3학년"];
alert(grade.shift()); // 1학년
alert(grade); // 2학년,3학년
let grade = ["1학년", "2학년", "3학년"];
grade.unshift("0학년");
alert(grade); // 0학년,1학년,2학년,3학년
✅ 배열의 내부 동작 원리
- 배열은 특별한 종류의 객체이다. 키가 숫자라는 점이 다르다.
- 키가 숫자이기 때문에 배열은 객체 기본 기능 이외에도 순서가 있는 컬렉션을 제어하게 해주는 특별한 메서드를 제공한다.
- 배열도 본질은 객체이기 때문에 length라는 프로퍼티도 제공한다.
※ 컬렉션
연관있는 자료들을 모아놓은 자료구조..?
- 배열을 배열답게 만들어주는 것은 특수 내부 표현방식이다.
자바스크립트 엔진은 배열의 요소를 인접한 메모리 공간에 차례로 저장해 연산 속도를 높인다.
이 외에도 배열 관련 연산을 더 빠르게 해주는 최적화 기법이 다양하게 있다.
► 다만 개발자가 배열을 '순서가 있는 자료의 컬렉션'처럼 일반 객체처럼 다루면 최적화 기법 등은 제대로 동작하지 않는다.
📌 배열을 일반 객체처럼 다루는 경우
- 배열의 길이보다 훨씬 큰 숫자를 사용해서 프로퍼티를 만들 때
► 요소를 역순으로 채우거나, grade[99998]과 같이 특정 인덱스에만 값을 채우고 그 사이에는 아무런 요소가 없는 경우
let grade = [];
grade[99998] = 'Hello';
- 임의의 이름을 사용해서 프로퍼티를 만들 때
► 숫자가 아닌 값을 프로퍼티 키로 사용하는 경우
let grade = [];
grade.age = 10;
- 배열은 객체이므로 위와 같이 프로퍼티를 추가해도 문제가 발생하지 않는다.
- 하지만, 이렇게 작성하면 자바스크립트 엔진이 배열을 일반 객체처럼 다루기 때문에
배열을 다룰 때만 적용되는 최적화 기법이 동작하지 않아서
배열 특유의 이점이 사라진다.
✅ 성능
- push / pop은 빠르지만 shift / unshift는 느리다.
- 간단하게 생각해봐도, 배열 앞에 값을 빼내고 나머지 요소들을 한 칸씩 앞으로 이동시키는 것은
배열에 요소가 많아질수록 요소가 이동하는데 걸리는 시간이 길고 메모리 관련 연산도 많아지기 때문에 느릴 수 있다.
- 하지만 반대로 배열의 뒤에서 값을 빼내면, 나머지 요소들의 인덱스를 그대로 유지해둘 수 있으므로
실행 속도가 더 빠르다.
✅ 반복문
- 배열을 순회할 때 사용하는 반복문은 다음과 같다.
► for
► for...of : 현재 요소의 인덱스는 얻을 수 없고 값만 얻을 수 있다.
► for...in : 배열도 객체형에 속하므로 for...in문을 사용할 수 있다.
let grade = ["1학년", "2학년", "3학년", "4학년", "5학년", "6학년"];
for (let number of grade) {
console.log(number);
}
for (let key in grade) {
console.log(grade[key]);
}
- 다만 for...in문은 다음과 같은 특징을 지니기 때문에 배열에 사용하는 것을 추천하지 않는다. (문제가 발생할 수 있다)
► 모던 자바스크립트 내용 발췌 (출처 : https://ko.javascript.info/array)
1. for..in 반복문은 모든 프로퍼티를 대상으로 순회합니다.
키가 숫자가 아닌 프로퍼티도 순회 대상에 포함됩니다.
브라우저나 기타 호스트 환경에서 쓰이는 객체 중, 배열과 유사한 형태를 보이는 ‘유사 배열(array-like)’ 객체가 있습니다.
유사 배열 객체엔 배열처럼 length 프로퍼티도 있고 요소마다 인덱스도 붙어 있죠.
그런데 여기에 더하여 유사 배열 객체엔 배열과는 달리 키가 숫자형이 아닌 프로퍼티와 메서드가 있을 수 있습니다.
유사 배열 객체와 for..in을 함께 사용하면 이 모든 것을 대상으로 순회가 이뤄집니다.
따라서 ‘필요 없는’ 프로퍼티들이 문제를 일으킬 가능성이 생깁니다.
2. for..in 반복문은 배열이 아니라 객체와 함께 사용할 때 최적화되어 있어서 배열에 사용하면 객체에 사용하는 것 대비 10~100배 정도 느립니다.
for..in 반복문의 속도가 대체로 빠른 편이기 때문에 병목 지점에서만 문제가 되긴 합니다만,
for..in 반복문을 사용할 땐 이런 차이를 알고 적절한 곳에 사용하시길 바랍니다.
✅ length 프로퍼티
- 배열에 무언가 조작을 가하면 length 프로퍼티가 자동으로 갱신된다.
- length 프로퍼티는 배열 내 요소의 개수가 아니라 가장 큰 인덱스에 1을 더한 값이다.
let grade = ["1학년", "2학년", "3학년", "4학년", "5학년", "6학년"];
console.log(grade.length); // 6
grade[200] = 'None';
console.log(grade.length); // 201
- length의 독특한 특징 중 또 하나는 [쓰기가 가능하다]는 점이다.
► 값을 수동으로 증가시키면 아무 일도 일어나지 않지만
► 값을 감소시키면 배열이 잘린다.
► 잘린 배열은 다시 되돌릴 수 없다.
let grade = ["1학년", "2학년", "3학년", "4학년", "5학년", "6학년"];
// length 증가시키기
grade.length++;
console.log(grade.length); // 7
// length 줄이기
grade.length = 3;
console.log(grade.length); // 3
alert(grade); //1학년,2학년,3학년
// length 다시 복구해보기
grade.length = 6;
alert(grade); //1학년,2학년,3학년,,,
✅ new Array()
- new Array() 를 통해서 배열을 만들 수도 있다.
- 잘 사용되지는 않는다고 한다.
► new Array()에 까다로운 기능이 있기 때문에..
- 숫자형 인수를 하나 넣어서 new Array를 호출하면 배열이 만들어진다.
다만 까다로운 점은... 배열엔 요소가 없는데 길이는 인수와 같아진다.
► new Array(3)으로 배열을 만들면 length는 3이 된다.
let grade = new Array(3);
console.log(grade.length); // 3
► 다만 배열의 요소들을 출력해보면 모두 undefined이다. (요소가 하나도 없다)
for (let value of grade) {
console.log(value); //undefined
}
- 이런 뜻밖의 상황을 마주치지 않기 위해서 new Array의 기능을 잘 사용하지 않는다고 한다.
✅ 다차원 배열
- 2차원, 3차원 배열로 선언할 수 있다.
/* 메모리에는 1차원으로 저장되겠지만... */
- 다차원 배열은 행렬을 저장하는 용도로 쓰인다.
let grade = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
alert(grade); //1,2,3,4,5,6,7,8,9
alert(grade[0][0]); // 1
alert(grade[1][0]); // 4
✅ toString 메서드
- 배열에도 있다. toString 메서드
/* 저번에 숫자형 공부할 때 toString 메서드를 배웠고 객체의 형 변환할 때도 toString을 호출한다고 배웠었다 */
- 이를 호출하면 쉼표로 구분한 문자열이 반환된다.
► alert으로 출력한 결과처럼
- 배열에는 Symbol.toPrimitive나 valueOf 메서드가 없다.
따라서 배열이 문자열로 형 변환이 일어날 때는 다음과 같이 변환된다.
[] → 빈 문자열
[1] → 문자열 "1"
[1,2] → 문자열 "1,2"
'2. 프로그래밍 언어 공부 > JavaScript' 카테고리의 다른 글
[공부 필기] JavaScript 문법 공부 26일차 (2) (0) | 2022.05.27 |
---|---|
[공부 필기] JavaScript 문법 공부 26일차 (1) (0) | 2022.05.27 |
[공부 필기] JavaScript 문법 공부 25일차 (1) (0) | 2022.05.26 |
[공부 필기] JavaScript 문법 공부 24일차 (0) | 2022.05.25 |
[공부 필기] JavaScript 문법 공부 23일차 (3) (0) | 2022.05.24 |