[새싹 프론트엔드] 11/9 (클래스)
01. 클래스
객체가 가져야 할 기본적인 정보를 담은 코드. 객체를 효율적으로 생성하기 위해 만들어진 구문이며 일종의 설계도라 할 수 있다. 붕어빵 틀(클래스)과 붕어빵(인스턴스)
생성자 함수와 클래스의 차이
- 생성자 함수 | function Animals(){}
호출 시 new 키워드가 생략되면 일반 함수로 인식된다. - 클래스 | class Animals{constructor{}}
호출 시 new 키워드 생략되면 타입 에러가 발생한다. class 키워드로 정의하며 내부에 constructor 필수.
생성자 함수와 클래스는 같은 기능을 하지만 형태만 다른 것이라고 보면 된다.
class Rectangle {
constructor{ // 객체를 생성하고 초기화하는 메서드
}
}
let rec1 = new Recangle(); // rec1은 클래스로 만들어낸 인스턴스
02. 클래스 내부 함수
- 생성자 메서드 (constructor)
- 프로토타입 메서드
- 정적 메서드
생성자 메서드
객체를 생성하고 초기화하는 메서드로 클래스 내에 최대 1개만 존재한다. 매개변수가 없을 경우에만 생략이 가능하며 생략 시 빈 생성자가 만들어진다.
생성자 메서드의 return 문은 생략해야 한다. new 연산자가 클래스와 함께 호출되면 암묵적으로 객체를 반환해 주기 때문.
※ return 값에 {} 빈 객체를 넣으면 빈 객체를 리턴. 다른 값을 지정해도(ex. return "soo") 그 값이 리턴되는 게 아니라 지정된 constructor의 값이 객체로 리턴된다.
class Rectangle {
constructor(w, h) {
this.width = w;
this.height = h;
}
}
let rec1 = new Rectangle(100, 200); // 클래스로 객체 생성
클래스로 생성한 객체 값 접근
객체이름.프로퍼티이름
rec1 = new Rectangle(100, 200);
// width에 접근하려면
rec1.width
<< 100
프로토타입 메서드
클래스 내부에서 명시적으로 정의한 메서드. 내가 만든 함수이지만, function 키워드를 사용하면 안 된다.
class Rectangle {
constructor(w, h) {
this.width = w;
this.height = h;
}
area() {
let areaResult = this.width * this.height; // this로 만들어진 객체의 값을 사용할 수 있다.
return areaResult;
}
}
let rec1 = new Rectangle(100, 200);
rec1.area() // 프로토타입 메서드 호출
<< 20000
cf.) 프로토타입 메서드도 화살표 함수 사용이 가능하나, this를 사용하지 못하는 등 여러 가지 제약이 있어 화살표 함수 사용은 권장하지 않는다.
정적 프로퍼티와 정적 메서드 (static)
클래스 자체에 선언된 프로퍼티 또는 메서드로 객체를 생성하지 않아도 호출이 가능하다.
class Rectangle {
constructor(w, h) {
this.width = w;
this.height = h;
}
static color = "blue";
static area(){
console.log(`사각형의 넓이를 구합니다.`)
}
}
정적 메서드와 프로토타입 메서드의 차이
구분 | 정적 메서드 | 프로토타입 메서드 |
프로토타입 체인 | 클래스 | 인스턴스 |
호출 방식 | 클래스로 호출 | 인스턴스로 호출 |
인스턴스 프로퍼티(this) 참조 가능 여부 | 불가능 | 가능 |
정적 메서드는 클래스 내에서 인스턴스 프로퍼티(this)참조가 불가능하기 때문에 클래스 이름을 사용해서 호출해야 한다.
ex.) Rectangle.color
03. 접근 제어
캡슐화(Encapsulation)
클래스 내부의 특정 프로퍼티나 메서드를 외부에서 참조하지 못하도록 숨기는 것. 캡슐화를 원하는 프로퍼티나 메서드 앞에 # 기호를 붙인다.
접근자 프로퍼티 사용 시 #을 붙여서 호출해야 한다.
클래스 외부 | 제한된 접근 권한을 제공
클래스 내부 | 원하지 않는 외부의 접근에 대해 내부를 보호
class Rectangle {
constructor(w, h) {
this.width = w;
this.height = h;
}
#color = "blue";
}
let rec1 = new Rectangle(100, 200);
rec1.#color
<< SyntaxError: Private field~~ 발생
04. 접근자 프로퍼티
- 데이터 프로퍼티 | 키와 값으로 구성된 일반적인 프로퍼티
- 접근자 프로퍼티 | 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 수정할 때 호출되는 접근자 함수로 구성된 프로퍼티
함수이지만, 호출은 함수 호출 방식이 아닌 프로퍼티 호출 방식으로 호출한다.
※ getter 함수와 setter 함수를 통해 캡슐화된 정보(#으로 정의된 private 변수)를 보고, 수정할 수 있다.
get | 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수 getter 함수가 호출되고 그 결과가 프로퍼티 값으로 반환 |
set | 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수 setter 함수가 호출되고 그 결과가 프로퍼티 값으로 저장 |
class Rectangle {
constructor(w, h) {
this.width = w;
this.height = h;
}
get display() {
return `가로는 ${this.width}, 세로는 ${this.height}입니다.`;
}
set changeWidth(value) {
this.width = value;
}
}
05. 상속
클래스 상속
한 클래스가 다른 클래스에서 정의된 속성 및 함수를 물려받아 그대로 사용. (super)
상속 받아 만들어진 클래스의 특징 : 물려받은 기능에 필요한 기능을 추가하여 정의할 수 있음
class 클래스이름 extends 부모클래스이름 {
클래스 구현
}
// 부모 클래스
class Animal {
constructor(legs, color) {
this.legs = legs;
this.color = color;
}
speak() {
console.log(`소리낸다.`);
}
sleep() {
console.log(`잔다.`);
}
}
// 자식 클래스
class Dog extends Animal {
constructor(legs, color, ownerName) {
super(legs, color);
this.ownerName = ownerName;
}
play() {
console.log(`신나게 논다.`);
}
sleep() {
super.sleep();
console.log(`많이 잔다.`);
}
}
오버라이딩(overriding)
부모 클래스로부터 상속받은 메서드를 자식 클래스에서 재정의
sleep() {
// super.sleep() 삭제
console.log(`많이 잔다.`); // 오버라이딩. 재정의
}
instanceof 연산자
객체가 특정 클래스에 속하는지 아닌지를 확인해주는 연산자로 해당 클래스에 속하면 true 아니면 false를 리턴한다.
dog instanceof Animal; // 위 코드에서 dog를 정의한 적 있으므로 true
cat instanceof Animal; // cat을 정의한 적은 없으므로 false
'새싹DT 기업연계형 프론트엔드 실무 프로젝트 과정 4주차 블로그 포스팅'