class
는 객체를 생산하는 공장, 틀이란 표현으로 자주 사용됩니다.class
를 통해 원하는 틀의 객체를 만들고, 비슷한 모양의 객체로 공장처럼 찍어낼 수 있습니다.- 자바스크립트에서
class
는prototype
를 기반으로 좀 더 직관적이고, 작성하기 쉽게 나온 ES6 문법 입니다.- 이렇게 내부적으로 동작은 동일하지만 더 보기 좋고 편리하게 개선된 문법을 Syntax Sugar(신텍스 슈거)라고 합니다.
👉 class는 prototype를 개선한 🧂 Syntax Suger 입니다.
function Person(name) {
this.name = name;
}
Person.prototype.introduce = function() {
console.log(`안녕하세여 저는 ${this.name}입니다.`);
}
const person = new Person('Jon');
person.introduce();
class Person(){
constructor(name) {
this.name = name;
}
introduce() {
console.log(`안녕하세여 저는 ${this.name}입니다.`);
}
}
- 위 코드처럼 prototype에서 프로퍼티를 추가하기 위해서는 따로 prototype에 접근하여 프로퍼티를 추가해야합니다.
- class의 경우 class에 내에서 한 번에 프로퍼티를 추가할 수 있어 더 직관적이고 쉽다는 것을 알 수 있습니다.
class
는 class 키워드를 붙여 생성하고, 앞글자는 대문자로 하는 것이 관례입니다.class
로 생성된 객체를 인스턴스 객체라고 합니다.- 인스턴스 객체는 생성자 함수에 new 키워드를 붙여 생성합니다.
construtor
는 인스턴스 생성시 호출되며 인자를 받아서 프로퍼티를 초기화 합니다.
construtor
class에 하나만 사용 가능 합니다.- 필요없을 시 생략이 가능합니다.
this
는 class로 생서된 인스턴스 객체를 의미합니다.- class에서 정의된 메서드는
prototype
에 저장됩니다.
class Animal {
constructor(eat) {
this.eat = eat;
}
introduce() {
console.log(`나는 ${this.eat}를 좋아하는 동물이야`);
}
move() {
console.log("달려서 이동중...");
}
}
const 초식동물 = new Animal('초식');
console.log('Animal 클래스로 생성 : ',초식동물);
초식동물1.introduce();
constructor
에 eat을 인자로 받아 초식동물이라는 인스턴스 객체를 생성합니다.
- class의 상속은 부모 자식의 관계를 가집니다.
- class에서 상속은 extends 키워드를 사용합니다.
아래 예시 코드를 보면서 상속에 대해 살펴봅시다.
class Animal {
constructor(eat) {
this.eat = eat;
}
introduce() {
console.log(`나는 ${this.eat}를 좋아하는 동물이야`);
}
move() {
console.log("달려서 이동중...");
}
}
class 초식동물 extends Animal {
constructor(name){
super('초식');
this.name = name;
}
introduce() { // 오버라이딩
super.introduce();
console.log(`내 이름은 ${this.name}이야`);
}
}
const 기린 = new 초식동물('기린');
console.log('Animal를 상속받은 초식동물 클래스로 생성 : ',기린);
기린.introduce();
- 위와 같이 자식 extends 부모 키워드를 사용하여 자식인 초식동물 클래스에서 Animal클래스인 move() 메서들을 사용할 수 있습니다.
- super()를 사용하면 부모 클래스의 값을 참조하여 그 값을 사용할 수 있습니다.
- constructor 안에서는 부모의 constructor를 가르킵니다.
- 메서드 안에서는 해당 부모 클래스를 가르킵니다.
- 상속받은 자식 클래스에 constructor를 사용한다면 반드시
super()
사용해야 합니다.- 부모에서 상속받은 constructor를 초기화 하지않고 생략하기 때문입니다.
- 위 예시에서 초식동물 클래스에서 construtor에서
super()
사용하여 부모 클래스의 construtor를 사용하여 초식이라는 인자를 전달하여 주었고, name 프로퍼티를 추가하였습니다.- 부모 클래스와 같은 메서드를 다시 자식에서 다시 선언하면
그 메서드은 덮어쓰여집니다. 이것을 Overriding(오버라이딩) 이라고 합니다.- 위 예시에서는 introduce() 메서드를 오버라이딩하고 있으며, 그 안에는
super
를 사용하여 부모클래스의 접근해 introuce() 메서드를 넣고, 추가적으로 이름을 출력해주는 기능을 추가하였습니다.
- class내에서 construtor 밖에서 this를 사용하지 않고, 프로퍼티를 정의하는 것을 의미합니다.
class Animal {
friend = '토끼';
constructor(eat) {
this.eat = eat;
}
introduce() {
console.log(`나는 ${this.eat}를 좋아하는 동물이야`);
}
move() {
console.log("달려서 이동중...");
}
}
const 초식동물 = new Animal('초식');
console.log('field 영역에 friend 추가 : ', 초식동물);
초식동물2.introduce();
위 코드에서는 construtor에 friend 프로퍼티를 정의하지 않았지만 인스턴스 생성시 friend: 토끼 라는 프로퍼티가 정상적으로 생성된 것을 알 수 있습니다.
- ES6에 도입된 문법으로 class 내부에
static
키워드를 사용하여 정의합니다.- 인스턴스 객체 개수와 상관없이 메모리 한 곳만 차지 합니다.
- 인스턴스 없이 클래스에서 바로 호출할 수 있습니다.
- 하지만 인스턴스에서는 정적필드에 접근이 불가능 합니다.
- 정적 메서드에서는 정적 필드만 사용가능합니다.
class의 정적 필드 사용 예시 코드
class Person {
static job = "개발자";
static introduceJob(){
console.log(`저의 직업은 ${this.job}입니다.`);
}
constructor(name, age){
this.name = name;
this.age = age;
}
introduce() {
console.log(`안녕하세요 저는 ${this.name}입니다. 나이는 ${this.age}세 입니다.`)
}
}
Person.introduceJob();
const jon = new Person('jon', 20);
console.log(jon);
jon.introduce();
위 코드에서 생성한 person 인스턴스 객체는
static
필드에 존재하는introduceJob()메서드와 job 프로퍼티에 접근할 수 없습니다.
하지만 Person class 자체에서는 접근이 가능하는 것을 볼 수 있습니다.
- 여기서 은닉화란 객체 내부의 값에 접근을 제한하는 것을 의미합니다.
private field
와getter
,setteter
함수를 통해 은닉화 할 수 있습니다.private field
는 ES6에 도입된 문법으로 외부에서 해당 프로퍼티에 접근하지 못하도록 만들어 줍니다.
- field에
#
를 붙인 프로퍼티를 먼저 선언해 준 후 constructor에 사용해야합니다.- class 내부에서는 접근이 가능합니다.
getter
,setter
함수는 스스로 값을 갖지 않고, 다른 프로퍼티의 값을 읽거나 저장할 때 사용됩니다.
get
,set
를 앞에 붙여 사용합니다.get
,set
은 같은 이름으로 사용되어야 합니다.- 함수이지만 프로퍼티 처럼 사용됩니다.
class Animal3 {
#eat = ''; // private 필드 생성
constructor(eat){
this.#eat = eat;
}
get favriteFood() {
return this.#eat;
}
set favriteFood(eat){
// 설정을 제한할 수도 있습니다.
if(eat==='육식') return console.log('나는 육식동물이 아니야');
return this.#eat = eat;
}
introduce() {
console.log(`나는 ${this.#eat}를 좋아하는 동물이야`);
}
move() {
console.log("달려서 이동중...");
}
}
const 초식동물3 = new Animal3('초식');
console.log('private 필드 프로퍼티 접근불가 : ',초식동물3);
console.log('setter 함수를 통한 프로퍼티 출력 : ',초식동물3.favriteFood);
초식동물3.favriteFood = '육식'; // 육식을 넣으면 접근 제한
초식동물3.favriteFood = '풀';
console.log('getter함수로 프로퍼티 변경 후 setter 함수를 통한 프로퍼티 출력 : ',초식동물3.favriteFood);