Class
- ES6에서 class 도입, 다른 언어와 조금 다르다
- Class는 field & method로 구성되어 있다
- Class는 붕어빵을 만들 수 있는 틀, 청사진, template이라고도 불린다
- Class 자체에는 data가 들어 있지 않고 틀(template)만 정의해 놓는다
- 이 Class에는 이런 이런 data가 들어올 수 있어라고 정의
- constructor : 생성자
- 함수를 만들면 자동으로 prototype으로 등록이 된다
- field (속성) : name, age ... 등
- mathod (행동) : speak();
class person{
name;
age;
speak();
};
- Class는 method 없이 field로만 구성 할 수 있다. (data class)
- encapsulation(캡슐화) : 안에서만 사용하게 하거나 밖에서도 사용할 수 있게 해준다
- 상속 & 다향성
- template
- declare once
- no data in
01. Object(객체)
- class를 이용해서 실제로 data로 만든 것
- class를 이용해서 새로운 인스턴스를 생성하면 object가 된다
- class는 정의만 하여 메모리에 들어가지는 않지만 데이터를 넣으면 object는 메모리에 올라간다
- instance of a Class
- created many times
- data in
02. Class
- Class : template
- Object : instance of a Class
- introuced in ES6
- syntactical sugar over prototype-based inheritance
- 진정한 의미로 class가 아닌 기존의 프로토 타입을 베이스로 간편하게 사용할 수 있게 Class만 추가 되었다
class Animal {
constructor(type, name, sound) {
this.type = type;
this.name = name;
this.sound = sound;
}
say() {
console.log(this.sound);
}
}
console.log(Animal.prototype.say);
const dog = new Animal('개', '멍멍이', '멍멍');
const cat = new Animal('고양이', '야옹이', '야옹');
class Dog extends Animal {
constructor(name, sound) {
super("개", name, sound);
}
}
class Cat extends Animal {
constructor(name, sound) {
super("고양이", name, sound);
}
}
const dog = new Dog('멍멍이', '멍멍');
const cat = new Cat( '야옹이', '야옹');
// test
class Food{
constructor(name) {
this.name = name;
this.brand = [];
}
addBrand(brand) {
this.brand.push(brand);
}
print() {
console.log(`${this.name}을/를 파는 음식점들 : `);
console.log(`${this.brand.join(", ")}`);
}
}
const pizza = new Food("피자");
pizza.addBrand("피자헛");
pizza.addBrand("도미노 피자");
const chicken = new Food("치킨");
chicken.addBrand("굽네치킨");
chicken.addBrand("BBQ");
//자서분리
pizza.print();
chicken.print();
1. Class declarations
class Person {
//constructor, 생성자, objec를 만들 때 필요한 data를 전달
constructor(name, age) {
//fields(변수)
this.name = name;
this.age = age;
}
//methods(함수)
speak() {
console.log(`${this.name} : hello`);
}
}
// object 생성
const ellie = new Person('ellie', 20);
console.log(ellie.name);
console.log(ellie.age);
ellie.speak();
2. Getter and Setter
- field : firstName, lastName, _age
class User {
constructor(firstName, lastName, age) {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
get age() {
return this._age;
}
set age(value) {
// 이렇게 직접적으로 경고를 주어도 되고
// if(value < 0) {
// throw Error('age can not ne negative');
// }
// 삼항연산자를 통해서 - 값이 들어오면 0으로 초기화를 해주어도 된다
this._age = value < 0 ? 0 : value;
}
// getter, setter을 사용할 경우 constructor안에 age로 인해 문제가 생긴다
// constructor의 this.age는 get 메소드를 호출하게 되고
// constructor의 = age는 set 메소드를 호출하게 되는데
// 그렇게 계속 호출을 하게 되면 class stack exceeded로 닫히게 된다
// 그렇기에 get, set 안에 변수 명은 _을 붙여서 다르게 정의해 준다
}
// 객체지향적으로 맞지않는 로직이다, 사람나이는 -가 될 수 없다
// 방어적인 자세로 만들어 줄 수 있는 것이 getter, setter이다
const user1 = new User('Steve', 'Job', -1);
// _age로 filed가 되어 있어도 .age로 호출이나 할당을 할 수 있는데
// 그 이유는 내부적으로 getter & setter을 이용하기 때문이다
console.log(user1.age);
3. Fields ( public, private)
- 최근에 업데이트 되어 아직까지 사용하기 부적합하며 사용시 babel을 이용해야 된다
Class Experiment {
// constructor을 이용하지 않고도 field를 정의할 수 있다
// 그냥 정의하게 되면 외부 접근이 가능
publicField = 2;
// #을 이용하여 외부 접근 불가, 클래스 내부에서 접근 변경 등이 가능하다
#privateField = 0;
}
const experiment = new Experiment();
console.log(experiment.publicField);
console.log(experiment.privateField);
4. Static properties and methods
- public static과 동일, 아직까지 사용하기는 부족합하다
Class Article {
// object & data에 상관 없이 class가 가진 고유의 value
// data 상관 없이 동일하게 반복적으로 사용되는 method
// static이라는 keyword를 사용하면 된다
// object에 상관없이 class 자체에 연결되어 있다
static publisher = 'Dream Coding';
constructor(articleNumber) {
this.ariticleNumber = articleNumber;
}
static printPublisher() {
console.log(Article.publisher);
}
}
const article1 = new Article(1);
const article2 = new Article(2);
// undefined, static은 object마다 할당되는 것이 아니다
console.log(article1.publisher);
// Dream Coding, Aticle이라는 class자체에 할당되어 있다
console.log(Article.publisher);
// static을 호출할 때는 class자체를 이용한다
Article.printPublisher();
// object에 상관없이 정통적으로 class에서 사용해야 되는 경우
5. extends(상속, Inheritance) & 다향성(상속 받은 field & method를 재 정의(overriding))
- class에 공통된 field & method가 있다면 하나의 부모 Class에 공통된 부분을 넣고 상속을 시키면 좋다
- a way for one class to extend another class
class Shape {
constructor(width, height, color) {
this.width = width;
this.height = height;
this.color = color;
}
draw() {
console.log(`drwing ${this.color} color of`);
}
getArea() {
return this.width * this.height;
}
}
class Rectangle extends Shape {}
class Triangle extends Shape {
draw() {
// 부모의 메소드를 사용하는 super keyword
super.draw();
console.log('angle');
}
//override
getArea() {
return (this.width*this.height) / 2;
}
}
const rectangle = new Rectangle(20, 20, 'blue');
rectangle.draw();
console.log(rectangle.getArea());
const triangle = new Triangle(20, 20, 'red');
triangle.draw();
console.log(triangle.getArea());
6.Class checking: instanceOf
- class를 이용해서 만들어진 새로운 instance
- 왼쪽에 있는 object가 오른쪽에 있는 class인지 아닌지 확인 (true / false return)
- Object instanceOf Class
console.log(rectangle instanceOf Rectangle); // true
console.log(triangle instanceOf Rectangle); // false
console.log(triangle instanceOf Triangle); // true
console.log(triangle instanceOf Shape); // true
console.log(triangle instanceOf Object); // true