[Day 19] 객체 + 배열
객체 (Object)
-
한꺼번에 여러 값을 담을 수 있는 통(container)과 같은 자료구조.
-
객체 안에는 이름-값 쌍(name-value pair)이 저장되는데, 이를 객체의 속성(property)이라고 한다.
-
속성 접근자(property accessor)
- 점 표기법 :
person.name = '이름';
- 대괄호 표기법 :
person['한국 나이'] = 20;
- 자바스크립트에서 식별자로 허용되지 않는 문자가 들어간 속성 이름을 사용해야 하는 경우에는 반드시 대괄호 표기법을 사용해야 한다.
- 접근하고자 하는 속성 이름을 현재 시점에서 모르는 경우에도 대괄호 표기법을 사용한다. (ex. 사용자 입력을 받아 속성을 생성하거나 할 때)
- 점 표기법 :
-
객체 다루기
// 속성 삭제하기 delete person.address; // 속성이 객체에 존재하는지 확인하기 'name' in person; // true
-
메소드 (Method)
-
어떤 객체의 속성으로 접근해서 사용하는 함수
const person = { greet: function() { return 'hello'; } }; person.greet(); // 'hello'; // 위 예제와 완전히 똑같이 동작합니다. const person = { greet() { return 'hello'; } }; person.greet(); // 'hello';
-
메소드를 사용하면 데이터와 데이터에 관련된 동작을 객체라는 하나의 단위로 묶어서 다룰 수 있다. =>
객체 지향 프로그래밍
-
prototype
을 이용해 메소드를 직접 넣을 수 있다.Person.prototype.getOlder = function() { this.age++; }
-
-
this
this
키워드를 사용하면, 메소드 호출 시에 해당 메소드를 갖고 있는 객체에 접근할 수 있다.- 함수 내부의
this
키워드가 실제로 무엇을 가리킬 것인가는, 메소드가 어떻게 정의되는가에 의해 결정되는 것이 아니라 메소드가 어떻게 사용되는가에 의해 결정된다. - 어떤 객체의 메소드로 사용되느냐에 따라 메소드 내부의
this
가 가리키는 객체가 달라질 수 있다.
function introduce() { return `안녕하세요, 제 이름은 ${this.name}입니다.`; } const person1 = { name: '윤아준', introduce }; const person2 = { name: '신하경', introduce }; person1.introduce(); // 안녕하세요, 제 이름은 운아준입니다. person2.introduce(); // 안녕하세요, 제 이름은 신하경입니다.
- 화살표 함수에서는
this
의 작동방식이 아예 다르다.
-
생성자 (Constructor)
-
객체를 만들 때
new
키워드와 함께 사용하는 함수를 생성자라고 부른다.const obj = new Object();
-
생성자 정의하기
// 생성자 정의 function Person(name) { this.name = name; } // 생성자를 통한 객체 생성 const person1 = new Person('윤아준');
- function 구문을 통해
Person
이라는 생성자를 정의하고, 생성자 안에서는this
키워드를 사용해서 새로 만들어질 객체의 속성을 지정해 준다. new
키워드를 사용해서 객체를 생성하는 순간에 생성자 안에 있는 코드가 실행되어 객체의 속성이 지정된다.- 생성자는 대문자로 시작하게끔 이름을 짓는 것이 관례.
- function 구문을 통해
-
인스턴스 (Instance)
-
생성자를 통해 생성된 객체를 그 생성자의
인스턴스
라고 한다. -
instanceof
연산자를 사용하면, 객체가 특정 생성자의 인스턴스가 맞는지를 확인할 수 있다.person1 instanceof Person; // true
-
객체 리터럴을 통해 생성된 객체는
Object
의 인스턴스이다.const obj = {}; obj instanceof Object; // true
-
-
생성자와 일반적인 함수의 차이는 없다. 사용하기 나름. 이 부분은 자바스크립트의 부족한 점.
- ES2015 에서 생긴 객체를 만들어내는 역할만 하는 생성자가
Class
이다.
- ES2015 에서 생긴 객체를 만들어내는 역할만 하는 생성자가
-
배열 (Array)
-
배열은 객체의 일종이지만, 내부적으로 특별하게 취급되어 일반적인 객체들과는 다른 특징을 갖는다.
-
객체와 배열의 가장 큰 차이점은, 배열의 요소 간에는 순서가 있다는 점이다. 객체의 요소 간에는 순서가 없다.
-
배열은
Array
생성자의 인스턴스이다. 따라서 배열의 프로토타입으로Array.prototype
객체가 지정되어 있다. 이 객체에 저장된 많은 메소드를 활용해 배열을 조작할 수 있다. -
배열 생성하기
-
배열 리터럴
-
Array
생성자- 인수가 어떻게 들어오는지에 따라 동작 방식이 다르기 때문에 일관적이지 않다. (잘 안씀)
-
Array.of
정적 메소드Array
생성자의 단점을 보완하기 위해 ES2015에서 등장. (리터럴보다 불편해서 잘 안씀)
new Array(1, 2, 3); // 이렇게 하지 마세요! Array.of(1, 2, 3) // 대신 이렇게 하세요. // `Array.of` 정적 메소드는 인수가 하나이더라도 그 인수를 요소로 갖는 배열을 반환합니다. Array.of(1); // [1] // 생성자는 이런 용도로만 사용하세요. new Array(1000); // [empty × 1000]
-
Array.from
정적 메소드- 자바스크립트의 유사 배열 객체(array-like object)와 iterable이라는 개념 때문에, 이에 해당하는 값들을
Array.from
정적 메소드를 통해 배열로 변환할 수 있다.
// `string` 타입은 래퍼 객체를 통해 iterable로 다루어질 수 있습니다. Array.from('hello'); // ["h", "e", "l", "l", "o"]
- 자바스크립트의 유사 배열 객체(array-like object)와 iterable이라는 개념 때문에, 이에 해당하는 값들을
-
-
배열의 끝 부분에서 요소를 추가/제거하기
arr.push()
arr.pop()
- pop() 메소드는 배열에서 맨 마지막 요소를 꺼내면서 그 값을 반환값으로 갖는다.
- pop()을 계속해서 배열에 더이상 요소가 없다면 ‘undefined’ 를 반환한다.
-
배열의 시작 부분에서 요소를 추가/제거하기
arr.unshift()
arr.shift()
-
요소를 배열 중간에 삽입하기
arr.splice(index, quantity, [elements...])
- index 번째 요소부터 quantity 개를 elements로 바꿔치기 한다. (반드시 같은 개수의 요소만 바꿔치기 할 수 있는 것은 아니다.)
- 새 요소로 바꿔치기 하고, 바꿔치기 당한 기존 요소들을 반환값으로 갖는다.
- [elements…] 인수를 생략하면 요소를 제거한다.
- quantity를 0으로 하면 요소를 추가하는 것도 가능하다.
-
배열 뒤집기
arr.reverse()
-
배열 정렬하기
arr.sort(function)
- 인수로 비교 함수를 넘겨주고, 그 조건에 따라서 값이 정렬된다.
- 비교함수 작동방법
- 만약 어떤 두 값 a, b에 대해서 비교 함수
compare
를compare(a, b)
와 같이 호출했을때 :- 음수를 반환하면 a가 b 앞에 오도록 정렬한다.
- 0을 반환하면 a와 b를 같은 순서로 간주한다.
- 양수를 반환하면 b가 a 앞에 오도록 정렬한다.
- 만약 어떤 두 값 a, b에 대해서 비교 함수
- 인수로 비교함수를 넣지 않으면
sort
메소드는 먼저 요소를 전부 문자열로 변환한 후, 유니코드 코드포인트를 비교하는 방식으로 정렬한다. - 문자열을 사전순으로 정렬하려면
x.localeCompare(y)
로 비교함수를 넘겨준다.
-
배열 순회하기
-
for
구문 -
forEach
메소드 - ES5- 배열의 각 요소에 대해 함수를 호출할 수 있다.
const arr = [1, 2, 3]; arr.forEach((item, [index], [array]) => { console.log(`현재 ${index + 1}번째 요소에 대해 함수가 실행되고 있습니다.`); }); // item은 현재 순회중인 배열의 요소 // index는 요소의 인덱스 // array는 순회중인 배열
-
for...of
구문 - ES2015- Iterable 구문을 순회하기 위해 사용한다. (배열도 Iterable이기 때문에 배열에 사용 가능)
- 배열의 인덱스가 필요한 경우에는
forEach
메소드나for
구문을 사용해야 한다.
const arr = [1, 2, 3, 4, 5]; for (let item of arr) { console.log(item); } // 변수 item을 매번 새로 만들고, 변수가 블록 스코프이기 때문에 for문 안에서만 유효하다. 따라서 let이 아니라 const로 선언해도 작동한다.
-
-
배열로부터 새로운 값 생성 (원본 배열 조작 X, 새로운 배열 생성 O)
-
slice
- 배열의 일부분에 해당하는 새로운 배열을 반환한다.
arr.slice([index, index])
- 첫 번째 인수의 default===0, 두 번째 인수의 default===arr.length 이기 때문에 인수 없이 호출하면 배열 전체가 복사된다.
- slice는 얕은 복사(shallow copy)를 하기 때문에, 배열 안에 배열 또는 객체가 들어있을 때는 주의해서 사용해야 한다.
-
map
- 배열의 각 요소에 함수를 적용해서 그 반환값을 요소로 갖는 새로운 배열을 만든다.
const arr = [1, 2, 3, 4, 5]; arr.map((item, [index], [array]) => { return item * index; }); // [0, 2, 6, 12, 20]
-
concat
- 여러 배열을 연결해서 하나의 새 배열을 만든다.
-
reduce
- 모든 요소의 값을 종합해서 하나의 값으로 만드는 계산을 할 때 사용한다.
-
filter
- 원하는 요소만을 골라내어 새로운 배열을 생성한다.
- 메소드의 인수에는 진리값(boolean)을 반환하는 함수(predicate)를 주어야 한다.
- 진리값을 반환하는 함수는 (현재 요소, 인덱스, 배열) 세 인수를 받는다.
-
join
- 배열의 요소들을 문자열로 변환한 후, 메소드의 인자로 주어진 구분자(seperator)를 이용해 하나의 문자열로 결합해서 반환한다.
- 구분자를 넘기지 않으면 default로
,
가 사용된다.
-
요소 찾기
indexOf
: 배열의 왼쪽부터 검색해서 처음 만나는 요소의 인덱스를 반환한다.lastIndexOf
: 배열의 오른쪽부터 검색- 요소를 찾지 못하면 -1 을 반환한다.
find
: predicate를 이용해 왼쪽부터 검사해서 처음 만나는 요소를 찾는다.find
메소드는 요소 자체를 반환한다.- 못찾으면 undefined 를 반환.
- predicate 에는
(현재 요소, 인덱스, 배열)
세 인수를 넘길 수 있다.
findIndex
: predicate를 이용해 왼쪽부터 검사해서 처음 만나는 요소를 찾는다.findIndex
는 요소의 인덱스를 반환한다.- 못찾으면 -1 을 반환.
- predicate 에는
(현재 요소, 인덱스, 배열)
세 인수를 넘길 수 있다.
-
배열이 특정 조건을 만족하는지 판별하기 (return true false) includes
: 배열이 특정 요소를 포함하고 있는지를 판별한다.every
: predicate를 인수로 받아서 모든 요소가 조건을 만족하는지를 검사한다.some
: predicate를 인수로 받아서 조건을 만족하는 요소가 하나라도 있는지 검사한다.
-
배열인지 아닌지 판별하기
Array.isArray(item);
-
다차원 배열 (Multidimensional Array)
- 배열 속에 배열이 중첩되어 있는 자료 구조
const table = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ]; table[0][1]; // 2 table[2][0]; // 7
-
댓글남기기