MDN 정의에 따르면 배열이나 객체의 속성을 해체하여
그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식
배열(array)에서의 구조 분해 할당
let [a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
구조 분해 할당이라고 해서 특별한 문법적 형태가 다른 것이 아니라,
위처럼 할당받을 변수를 왼쪽에, 분해할 대상을 오른쪽에 해서 대입하는 형식으로 작성하면 됩니다.
배열 [10, 20] 이 분해되어 각각 a, b에 담긴 것입니다.
물론 아래와 같이 미리 저장해 둔 배열로부터 구조 분해 할당하는 형태도 당연히 가능합니다.
let array = [1, 2, 3];
let [a, b, c] = array;
console.log(a, b, c); // 1 2 3
여기서 또 활용되는 것이 앞의 포스팅에서 많이 보았던 ...
표현입니다.
이번 구조 분해 할당에서는 어떻게 쓰이는지 살펴보자면…
let array = [1, 2, 3, 4, 5];
let [a, b, ...rest] = array;
console.log(rest); // [3, 4, 5];
구조 분해 할당에서는 a, b 까지 1과 2가 대입이 되고,
나머지 3, 4, 5는 ...
rest 로 받아서 [3, 4, 5] 와 같이 rest 변수에 배열로 저장해 줍니다.
참고로 배열 구조분해 할당(array destructuring assignment)에서 위와 같이 쓰이는 ... 요소를
Rest elements 라고 부릅니다. (참고 : https://v8.dev/features/object-rest-spread)
...
문법의 역할이 Rest 일 때, 파라미터에서 쓰이면 Rest 파라미터,
위처럼 배열의 구조분해 할당에 쓰일 경우 Rest elements가 됩니다.
객체에서의 구조 분해 할당은 아주아주 많이 쓰이는 문법입니다.
객체 내부의 프로퍼티 값을 간편하게 분해해서 변수에 저장할 수 있게 해 줍니다.
배열에서의 구조 분해 할당과 쓰이는 의미는 동일하되,
쓰이는 대상이 객체로 바뀐 것 뿐입니다.
단, 분해되는 대상이 배열은 array
의 value(element)
였다면,
객체는 분해되는 대상이 객체의 property
인 차이가 있습니다.
const obj = {
name: "John",
age: 18,
memo: "Hello",
};
const { name, age, memo } = obj;
console.log(name); // "John"
console.log(age); // 18
console.log(memo); // "Hello"
// 만약 구조 분해 할당을 사용하지 않는다면?
// 아래와 같이 직접 대입해 주어야 한다...
const name = obj.name;
const age = obj.age;
const memo = obj.memo;
const obj = {
name: "John",
age: 18,
memo: "Hello",
};
const { name: YourName, age, memo } = obj;
console.log(YourName); // 'John'
객체 구조 분해 할당은 프로퍼티를 기준으로 하기 때문에,
배열 구조 분해 할당과 달리 그 순서가 뒤바뀌어도 전혀 문제없이 해당 프로퍼티의 값을 가져올 수 있습니다.
const obj = {
name: "John",
age: 18,
memo: "Hello",
};
// memo, name, age 순으로 작성해도 상관이 없다. 알아서 해당 프로퍼티명에 해당하는 값을 저장한다.
const { memo, name, age } = obj;
console.log(name); // 'John'
console.log(age); // 18
console.log(memo); // 'Hello'
// 새로운 map 을 만들고 map 에 key, value 엔트리를 추가
let me = new Map();
me.set('name', 'kevin');
me.set('age', 28);
console.log(me.get('age'); // 28
// 대괄호를 사용해서 map 을 선언하는 방법
const roomTypeMap = new Map(
[
["01", "원룸(오픈형)"],
["02", "원룸(분리형)"],
["03", "원룸(복층형)"],
["04", "투룸"],
["05", "쓰리룸"]
]
);
// 새로운 map 을 만들고 그 데이터를 기존의 [key, value] 페어컬렉션으로 채움
let you = new Map().set('name', 'paul').set('age', 34);
console.log(you.get('name')); // 'paul'
// has(): 주어진 key 가 존재하는지 확인
console.log(me.has('name')); // true
// size: map 에 담겨진 엔트리의 개수를 조회
console.log(you.size); // 2
// delete(): 엔트리를 삭제
me.delete('age');
console.log(me.has('age')); // false
// clear(): 모든 엔트리를 삭제
you.clear();
console.log(you.size); // 0
// 비어있는 새로운 set 을 만듬
let setA = new Set();
// 새로운 set 을 만들고 인자로 전달된 iterable 로 인자를 채움
let setB = new Set().add('a').add('b');
setB.add('c');
console.log(setB.size); // 3
// has(): 주어진 값이 set 안에 존재할 경우, true 를 반환
// indexOf() 보다 빠름. 단, index 가 없음
console.log(setB.has('b')); // true
// set 에서 주어진 값을 제거
setB.delete('b');
console.log(setB.has('b')); // false
// set 안의 모든 데이터를 제거
setB.clear();
console.log(setB.size); // 0
ES2015에서 도입된 클래스는 생성자의 기능을 대체합니다.
class
표현식을 사용하면,
생성자와 같은 기능을 하는 함수를 훨씬 더 깔끔한 문법으로 정의할 수 있습니다.
class Person { }
let kim = new Person();
console.log(kim); //person:{}
클래스는 다음과 같이 선언 할수 있으며 생성자Constructor
를 사용해 초기값을 설정할 수 있습니다.
class Human { //인터페이스와 유사, 타입스크립트에선 클래스의 속성과 권한을 적어줘야함.
public name: string;
public age: number;
public gender: string;
constructor(name: string, age: number, gender: string){//생성자.
//메소드로써 클래스가 시작할때마다 호출. 클래스로부터 객체를 만들때.
this.name = name;
this.age = age;
this.gender = gender;
}
}
클래스 상속(class inheritance, subclassing) 기능을 통해 한 클래스의 기능을 다른 클래스에서 재사용할 수 있습니다.
class Parent {
// ...
}
class Child extends Parent {
// ...
}
위 코드에서, extends
키워드를 통해 Child 클래스가 Parent 클래스를 상속했습니다.
이 관계를 보고 '부모 클래스-자식 클래스 관계' 혹은 '슈퍼 클래스(superclass)-서브 클래스(subclass) 관계'라고 말하기도 합니다.
어떤 클래스 A가 다른 클래스 B를 상속받으면, 다음과 같은 일들이 가능해집니다.
앞서 봤듯이, 자식 클래스에서 부모 클래스의 정적 속성과 인스턴스 속성에 접근할 수 있었습니다.
하지만, 자식 클래스에 같은 이름의 속성을 정의한 경우 문제가 생깁니다.
class Melon {
getColor() {
return '제 색깔은 초록색입니다.';
}
}
class WaterMelon extends Melon {
getColor() {
return '속은 빨강색입니다.';
}
}
const waterMelon = new WaterMelon();
waterMelon.getColor(); // 속은 빨강색입니다.
이런 경우에, super 키워드를 통해 부모 클래스의 메소드에 직접 접근할 수 있습니다.
class Melon {
getColor() {
return '제 색깔은 초록색입니다.';
}
}
class WaterMelon extends Melon {
getColor() {
return super.getColor() + ' 하지만 속은 빨강색입니다.';
}
}
const waterMelon = new WaterMelon();
waterMelon.getColor(); // 제 색깔은 초록색입니다. 하지만 속은 빨강색입니다.
super
키워드의 동작 방식은 다음과 같습니다.