[Javascript] 클래스 - getter/setter, 정적 메소드, 상속
Prototype
Array mdn을 검색해서 공식 문서를 읽어보자
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array
Array - JavaScript | MDN
JavaScript Array 클래스는 리스트 형태의 고수준 객체인 배열을 생성할 때 사용하는 전역 객체입니다.
developer.mozilla.org
프로토타입은 배열데이터(인스턴스)에서 쓸 수 있는 별도의 속성이나 메소드를 등록하는 객체이다.
내가 원하는 로직을 점표기법으로 붙여서 쓸 수 있다!
const fruits = new Array('apple', 'banana', 'cherry')
Array.prototype.seacrab = function() {
console.log(this)
}
fruits.seacrab()
이렇게 배열 데이터에서 사용할 수 있는 메소드를 만들 수 있다.
const heropy = {
firstName: 'yuna',
lastName: 'so',
getFullName: function() { // getFullName() {} 로 생략 가능
return `${this.firstName} ${this.lastName}`
}
}
const neo = {
firstName: 'neo',
lastName: 'ann',
}
console.log(heropy.getFullName())
console.log(heropy.getFullName.call(neo))
여기서 call()은 호출되는 대상 객체를 (heropy에서 neo로) 바꿔준다.
이와 동일하게 동작하는 로직을 prototype으로 만들어 보겠다.
getFullName 부분을 만드는거다!
function Food (fruits, price) {
this.fruitsName = fruits
this.priceName = price
}
Food.prototype.getFull = function() {
return `${this.fruitsName}는 ${this.priceName}원`
} // 화살표 함수 사용 X : this 키워드 정의가 달라지기 때문
const apple = new Food('사과', '2000')
const banana = new Food('바나나', '1400')
console.log(apple.getFull())
console.log(banana.getFull())
예제를 바꿔봤지만 getFull을 보면 된다.
이 메소드를 더 효율적으로 사용할 수 있다.
하지만 이를 ES6에서 나온 Class 문법으로 조금 더 간소화 할 수 있다.
ES6 Classes
class Food {
constructor(food, price) {
this.foodName = food
this.priceTag = price
}
getFull() {
return `${this.foodName}는 ${this.priceTag}원`
}
}
const apple = new Food('사과', '2000')
const banana = new Food('바나나', '1400')
console.log(apple.getFull())
console.log(banana.getFull())
어떻게 생겼는지 다시 뜯어보겠다.
class 변수 {
constructor(파라미터_매개변수) {
}
메소드() {
}
}
이러한 구조라고 볼 수 있다.
Getter, Setter
get, set은 함수 데이터 메소드 앞에 붙여서 사용하는 키워드이다.
속성처럼 사용이 가능해서 함수가 그때그때 동작해 새로운 데이터를 만든다.
class Food {
constructor(food, price) {
this.foodName = food
this.priceTag = price
}
get fullSent() { //getter 일때는 return 이 있어야 함.
console.log('getting full sentence')
return `${this.foodName}는 ${this.priceTag}원`
}
set fullSent(value) { //setter 일때는 파라미터가 1개 있어야 함. (2개 이상X)
console.log(value)
;[this.foodName, this.priceTag] = value.split(' ') // 띄어쓰기 기준으로 나눌거다
} // 배열 구조 분해 할당 ; 대괄호 앞 코드에 세미콜론이 꼭 있어야 해서 [] 앞에 붙여준다.
}
const apple = new Food('사과', '2000')
console.log(apple.fullSent)
// apple.food = 'banana'
// console.log(apple.fullSent)
apple.fullSent = '바나나 1500' //파라미터 1개로 들어가서 이 문장 그대로 출력된다.
주석에서 보이는 것처럼...
getter일때는 return이 있어야하고, setter일때는 파라미터가 1개 있어야 한다.(2개 이상X)
setter에 파라미터가 1개 이상 있을 경우 이 오류 메세지가 뜬다.
(1개 넣었는데도 이렇게 뜨길래 브라우저를 껐다가 다시 켰더니 오류가 사라졌다.
정적 메소드(Static methods)
isArray mdn 공식 문서를 참고하자.
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
Array.isArray() - JavaScript | MDN
Array.isArray() 메서드는 인자가 Array인지 판별합니다.
developer.mozilla.org
Array.isArray()
prototype이 붙어있지 않은 메소드를 정적 메소드라고 한다.
Array.prototype.method 형태여야 하는데 정적 메소드는 위와 같은 형태이다.
isArray()는 괄호 안에 인수를 받아서 배열 데이터인지 확인하고 불리안 데이터를 반환한다.
상속 (Inheritance)
상속을 사용하면 클래스를 다른 클래스로 확장할 수 있다.
// 운송수단
class Vehicle {
constructor(acceleration = 1) {
this.speed = 0
this.acceleration = acceleration
}
accelerate() {
this.speed += this.acceleration
}
decelerate() {
if (this.speed <= 0) {
console.log('정지!')
return
}
this.speed -= this.acceleration
}
}
//자전거
class Bicycle extends Vehicle {
constructor(price = 100, acceleration){
super(acceleration) //constructor 부분 상속 받음
this.price = price
this.wheel = 2
}
}
const bicycle = new Bicycle(300, 2)
bicycle.accelerate()
bicycle.accelerate()
console.log(bicycle)
console.log(bicycle instanceof Bicycle)
// 키워드 앞쪽의 데이터가 뒤쪽의 클래스에서 인스턴스로 만들어져있는지 확인하는 것
//자동차
class Car extends Vehicle {
constructor(license, price, acceleration) {
super(price, acceleration)
this.license = license
this.wheel = 4
}
// 오버라이딩(Overriding) : 기존 메소드를 덮어 쓰는 것
accelerate() {
if(!this.license) {
console.error('무면허!')
return
}
this.speed += this.acceleration
console.log('가속!', this.speed)
}
}
const carA = new Car(true, 7000, 10)
const carB = new Car(false, 4000, 6)
carA.accelerate()
carB.accelerate()
console.log(carA)
console.log(carB)
//보트
class Boat extends Vehicle {
constructor(price, acceleration) {
super(acceleration)
this.price = price
this.motor = 1
}
}
const boat = new Boat(10000, 5)
console.log(boat)
운송수단이라는 부모 class가 있고, 자전거, 자동차, 보트 클래스가 운송수단을 상속 받아 작성되었다.
오버라이딩(Overriding)으로 상속 받은 class의 내용을 덮어씌워 사용할 수도 있다.
instanceof 를 사용해서 어느 class에서 영향을 받은건지 알 수 있다.
코드가 길어 구조를 살펴보겠다.
class A {
constructor() {}
}
class B extends A {
constructor() {
super()
}
}
class C extends B {
constructor() {
super()
}
}
const a = new A()
const b = new B()
const c = new C()
console.log(c instanceof A)
console.log(c.constructor === C)
이렇게 상속은 extends 로 이뤄지고, 상속받은 class에는 super(사용할 인수)를 포함해야 한다.