자바스크립트도 C++처럼 클래스를 이용한 객체지향 프로그래밍 수행이 가능하다.
하지만 클래스라는 문법을 만들어놓은 것 뿐이지 실제로는 생성자함수와 프로토타입에 의한 설탕문법이다.
new
없는 호출은 무조건 에러extends
와 super
키워드 사용let
과 같은 호이스팅이 일어남 ( 일시적 사각지대 존재 )strict mode
로 지정됨[[Enumerable]]
이 false
이다.클래스도 일급객체다.
// 클래스 선언문
class Person {}
// 클래스 표현식
const Person = class MyClass {};
class Person {
// 생성자
constructor(name, firstText, lastText){
this.name = name;
this.fullText = firstText + lastText;
}
// 프로토타입 메서드
say(){
console.log("Hello, ", this.name);
}
// 정적 메서드
static hi(){
console.log("hi");
}
// 접근자
get fullText(){
return this.firstText + this.lastText;
}
set fullText(full){
[this.firstText, this.lastText] = full;
}
}
const person = new Person("john");
person.say(); // "Hello, john"
Person.hi(); // "hi"
생략시 constructor() {}
로 자동으로 생성됨
그리고 생성자 함수처럼 this
값이 자동으로 빈 객체로 생성되고 각종 처리후 this
값을 리턴한다.
객체가 가지는 메서드가 아닌 클래스 자체가 가지는 메서드
즉, 프로토타입체인에 존재하는 메서드가 아니라서 객체에서 사용할 수 없음
function Person(name){
this.name = name;
}
Person.hi = function() { console.log("hi"); };
Person.hi(); // "hi"
기존 클래스를 기반으로 새로운 클래스를 생성하는 것을 의미한다.
예를 들어 Animal
클래스에 동물들이 공통적으로 가지는 특성을 넣고 Bird
가 상속받아 자신만의 특성을 넣는 행위를 Bird
가 Animal
을 상속받는다 라고 말한다.
클래스의 extends
를 사용하지 않고 생성자 함수로 상속을 구현하려면 많은 일을 직접 처리해야한다.
1. apply()
를 통해 부모의 생성자 호출
2. Object.create()
를 통해 자식의 프로토타입 교체
3. constructor
를 직접적으로 교체
생략시 자동으로 생성되는 생성자가 존재함
super()
를 호출해야함[[HomeObject]]
자신을 바인딩하고 있는 객체의 참조값을 가짐
단, ES6축약표현으로 정의된 함수만이 [[HomeObject]]
를 가짐
5.3 super()
에서 참조시 부모클래스의 메서드를 호출가능함
이 가능한 이유가 [[HomeObject]]
때문이다.
부모클래스의 메서드를 호출하기 위해서는 부모클래스의 프로토타입을 알아야하고,
부모클래스의 프로토타입을 알려면 부모를 상속받는 자식의 객체를 알면 프로토타입 체인을 통해서 알아낼 수 있다.
자식의 객체가 메서드를 호출하면 그 메서드는 [[HomeObject]]
를 가지고 있고,
[[HomeObject]]
는 자신을 바인딩하고 있는 객체의 참조값을 가지니까 그 참조값을 이용해서 부모의 메서드를 호출할 수 있는 것이다.
[[ConstructorKind]]
[[ConstructorKind]]
을 통해서 부모클래스인지 자식클래스인지 구분할 수 있다.
부모클래스인경우 "base", 자식클래스인경우 "derived"로 설정된다.
자식클래스의 생성자를 명시적으로 작성할 때는 반드시 super()
를 맨위에 넣어줘야 한다고 했었다.
그 이유는 자식클래스는 부모클래스에서 인스턴스 생성을 위임하기 때문이다.
constructor
호출 후 this
바인딩 및 초기화constructor
에서 this
를 그대로 받아서 초기화this
값 반환class Parent {
constructor(x){
this.x = x;
}
say() {
return "Hi, ";
}
}
class Children {
constructor(x, y){
// 부모클래스의 생성자 호출 즉, Parent의 constructor호출
super(x);
this.y = y;
}
// 생략시 아래의 생성자가 자동으로 생성됨
// constructor(...args) { super(...args) }
say() {
return super.say() + "Hello, "; // Hi, Hello,
}
}
필드, 접근제한자, 생성자없이 사용하는 방법 등이 생성될 예정인것 같음