자바스크립트 클래스

정지훈·2020년 12월 8일
0

클래스

클래스를 한마디로 이야기 하면 클래스는 객체만을 생성하는 함수입니다.
(다른 일은 안 합니다.)

생성자 함수는 일반 함수로 호출할 수 있지만 클래스는 객체만을 위한 전용 함수입니다.

클래스는 생성자 함수와 유사한 부분이 많고 new와 함께 호출합니다. 즉 클래스도 함수 입니다.

클래스 기반 자바랑 유사한 문법을 갖고 있습니다.
클래스 내부도 프로토타입 기반으로 되어 있습니다.

하지만 클래스하고 생성자 함수랑 똑같다? 엄밀히 따지면 둘은 다릅니다.

클래스가 생성자 함수보다 더 엄격합니다.
예를들어 생성자 함수는 new를 안 붙여도 되지만 클래스는 안 붙이면 에러가 발생합니다.

생성자 함수는 내부적으로 new.target이 방어코드가 없어서 작성해 주는게 좋지만 클래스는 내부적으로 new.target에 방어코드가 있어서 없으면 에러가 발생합니다.

프로토타입 상속

class도 상속을 구현 할 수 있습니다. extends를 사용해 슈퍼 클래스를 상속받아 사용할 수 있습니다.

class 내부

클래스는 내부적으로 생성자 함수랑 비슷하게 돕니다.

class Person {
  constructor(name) { // 일단 constructor가 호출 된다고 생각! 사실은 아닙니다.
    console.log(this); // 의사코드 this = {};
    this.name = name;
    console.log(this); // Person { name: 'Jung' } 
    // 의사 코드 return this <- 내부에서 엔진이 암묵적으로 this를 return한다. 만약 빈객체를 명시적으로 리턴하면 {} 빈객체가 나온다. 
  }
}

class안에는 3가지 메서드를 정의 할 수 있습니다.

하나는 constructor 메서드
두번째는 프로토타입 메서드
세번째는 static메서드(정적 메서드)

2020년 7월 클래스 몸체에 메서드 뿐만이 아니라 프로퍼티를 직접 정의할 수 있는 새로운 표준 사양이 제안되어 있습니다.
이 제안 사양에 의해 머지않아 클래스 몸체에서 메서드 뿐반 아니라 프로퍼티도 정의할 수 있게 될 것으로 보입니다.


class Person {
constructor(name) {
this.name = name; 
// this.sayHi = function () { // 인스턴스 메서드
// console.log(`Hi My name ${this.name}`);
// };
}
sayHi() { // 이 메서드를 호출한 객체가 this
console.log(`Hi My name ${this.name}`)
}

static sayHi() {
console.log(`Hi`); // 이 정적메서드는 this는 Person식별자를 가리킨다.
}
}

const me = new Person('Jung');
// me.sayHi = function () {
// console.log(`Hi My name ${this.name}`);
// } // 인스턴스 메서드 추가
console.log(me);
console.log(me.sayHi()); // 프로토타입 메서드 호출
Person.sayHi(); // 정적 메서드 호출

그런데 여기서 잠깐!
class 안에 constructor는 메서드인가? 정확히 말해서는 메서드가 아니다!


class Person {
constructor(name) { // 이게 메서드인가?
this.age = name; 
}
sayHi() { // 이 메서드를 호출한 객체가 this
console.log(`Hi My name ${this.age}`);
}
static sayHi() {
console.log(`dddsf${this.age}`); // 이 this는 Person식별자를 가리킨다.
}
}

클래스 안에 constructor는 자바스크립트 엔진이 내부적으로 풀어서 함수의 문으로 만듭니다.

->의사코드
function constructor(name) {
	this.age;
	...
}

즉 정확히 말해서 메서드가 아니지만! 뭐라 부르기 애매한 부분이 있어서 그냥 메서드라고 칭하는 것 뿐

상속에 의한 클래스 확장

상속은 extends를 통해 만들 수 있다.

class Animal {
  constructor(age, weight) {
    this.age = age;
    this.weight = weight;
  }

  eat() { return 'eat'; }

  move() { return 'move'; }
}

// 상속을 통해 Animal 클래스를 확장한 Bird 클래스
class Bird extends Animal {
  fly() { return 'fly'; }
}

const bird = new Bird(1, 5);

console.log(bird); // Bird {age: 1, weight: 5}
console.log(bird instanceof Bird); // true
console.log(bird instanceof Animal); // true

console.log(bird.eat());  // eat
console.log(bird.move()); // move
console.log(bird.fly());  // fly

super 키워드

  • super를 호출하면 수퍼클래스의 constructor를 호출합니다.
  • super를 참조하면 수퍼클래스의 메서드를 호출할 수 있습니다.
// 수퍼클래스
class Base {}

// 서브클래스
class Derived extends Base {}

위 예제의 클래스에는 다음과 같이 암묵적으로 constructor가 정의됩니다.

// 수퍼클래스
class Base {
  constructor() {}
}

// 서브클래스
class Derived extends Base {
  constructor() { super(); }
}

const derived = new Derived();
console.log(derived); // Derived {}

위 예제와 같이 같이 수퍼클래스와 서브클래스 모두 constructor를 생략하면 빈 객체가 생성됩니다.

// 수퍼클래스
class Base {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
}

// 서브클래스
class Derived extends Base {
  // 다음과 같이 암묵적으로 constructor가 정의된다.
  // constructor(...args) { super(...args); }
}

const derived = new Derived(1, 2);
console.log(derived); // Derived {a: 1, b: 2}

인스턴스는 서브클래스가 만든 것 처럼 보이지만! 사실 서브 클래스가 슈퍼클래스한테 짬처리 시켜서 슈퍼클래스가 인스턴스를 생성하지만 서브클래스가 만든 것 처럼 보입니다.

0개의 댓글