다른언어 처럼 클래스 기반으로 동작하는것이 아니라 여전히 프로토타입 기반으로 동작한다.
프로토타입 기반 문법을 보기좋게 클래스로 바꾼것으로 생각하면 된다.
다음은 프로토타입 상속 예제 코드이다.
var Human = function(type) {
this.type = type || 'human';
};
Human.isHuman = function(human) {
return human instanceof Human;
}
Human.prototype.breathe = function() {
alert('h-a-a-a-m');
};
var Zero = function(type, firstName, lastName) {
Human.apply(this, arguments);
this.firstName = firstName;
this.lastName = lastName;
};
Zero.prototype = Object.create(Human.prototype);
Zero.prototype.constructor = Zero; // 상속하는 부분
Zero.prototype.sayName = function() {
alert(this.firstName + ' ' + this.lastName);
};
var oldZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(oldZero); // true
코드 설명
var Human = function(type) {
this.type = type || 'human';
};
처음 var Human 은 type에 값이 들어오면 그값을 Human.type으로 만들어준다 즉 이건 Human 생성자 함수이다.
Human.isHuman = function(human) {
return human instanceof Human;
}
들어온 인자가 Human의 속하거나 Human을 상속받는 클래스에 속하는지 확인한다.
💡[웹 개념/javascript] - instanceof
Human.prototype.breathe = function() {
alert('h-a-a-a-m');
};
이는 Human 의 prototype에 breathe라는 프로퍼티를 만들고 그 프로퍼티는 함수로 했다.
이해 예시
var Zero = function(type, firstName, lastName) {
Human.apply(this, arguments);
this.firstName = firstName;
this.lastName = lastName;
};
위의 코드는 zero 생성자 함수이다 위에 Human.apply(this, arguments); 부분을 보면 상속하는것을 알수 있으며 apply를 통해 Human에 arguments 객체(type,firstName,lastName)를 받는다 따라서 type을 먼저 받고 이후 firstname 과 lastname을 받는다.
Zero.prototype = Object.create(Human.prototype);
Zero.prototype.constructor = Zero; // 상속하는 부분
Zero.prototype.sayName = function() {
alert(this.firstName + ' ' + this.lastName);
};
var oldZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(oldZero); // true
이후 코드를 보게 되면 상속받기 위한 코드가 나와있는데 Object.create로 상속을 받은뒤 constructor 프로퍼티가 생성되었음으로 Zero를 상속시켜준다.
이후 sayName 함수를 선언하여 이후 출력시켜주는 함수이다.
Zero.prototype = Object.create(Human.prototype);
Zero.prototype.constructor = Zero; // 상속하는 부분
여기서 이부분을 왜해주는지 이해가 잘 안되었다 그래서 추가로 Object.create를 공부하여 답을 알아냈다
이제 위의 함수를 아래처럼 이쁘게 바꿀수가 있다.
class Human {
constructor(type = 'human') {
this.type = type;
}
static isHuman(human) {
return human instanceof Human;
}
breathe() {
alert('h-a-a-a-m');
}
}
class Zero extends Human {
constructor(type, firstName, lastName) {
super(type);
this.firstName = firstName;
this.lastName = lastName;
}
sayName() {
super.breathe();
alert(`${this.firstName} ${this.lastName}`);
}
}
const newZero = new Zero('human', 'Zero', 'Cho');
Human.isHuman(newZero); // true
전반적으로 class 안으로 그룹화된것을 볼수있다 다시 코드를 차근차근 살펴보자면
class Human {
constructor(type = 'human') {
this.type = type;
}
static isHuman(human) {
return human instanceof Human;
}
breathe() {
alert('h-a-a-a-m');
}
}
생성자 함수는 constructor 안으로 들어 갔고 Human.isHuman 같은 클래스 함수는 static 키워드로 전환 되었다.
프로토 타입 함수들도 모두 class 블록 안에 포함 되어 어떤 함수가 어떤 클래스 소속인지 보기 쉬워졌다.
class Zero extends Human {
constructor(type, firstName, lastName) {
super(type);
this.firstName = firstName;
this.lastName = lastName;
}
sayName() {
super.breathe();
alert(`${this.firstName} ${this.lastName}`);
}
}
상속도 간단해져서 extends 키워드로 쉽게 상속 가능해졌다. constructor(type, firstName, lastName)의 의미는 Zero 생성자로인해 constructor가 자동으로 생기고 생기자마자 실행되는 것을 의미한다.
이후 super를 통해 부모클래스의 생성자함수를 호출하여 type을 넘겨주는데 이렇게 하는 이유는 this를 사용하기 위해서 이다. 이 super를 안해주면 참조오류가 발생
이후 firstName과 lastName을 선언 해준다.
그리고 sayName함수에서는 breathe 함수가 부모 클래스에 있기에 super를 써서 가져오는걸 볼수 있다.
마지막으로 중요한점은 이렇게 클래스 문법으로 바뀌었더라도 자바스크립트는 프로토타입 기반으로 동작한다는 것을 명심해야한다.
'Node JS > ES2015+' 카테고리의 다른 글
async/await (0) | 2022.04.24 |
---|---|
프로미스 (0) | 2022.04.24 |
ES2015+ 란?? (0) | 2022.04.24 |
구조분해 할당 (0) | 2021.11.27 |
화살표 함수 (0) | 2021.11.27 |