모던자바스크립트입문] 18

18 생성자와 클래스 구문

18.1 생성자

18.1.1 생성자를 정의하는 방법

  • new 연산자로 객체를 생성(초기화해서 구축)
  • 이름이 같은 메서드와 프로퍼티를 가진 객체를 효율적으로 생성가능
  • 메서드를 생성자의 프로토타입에 추가할 경우 메모리 낭비를 피할 수 있고 다른 생성자에게 상속할 수 있음
  1. 함수선언문으로 정의하는 방법
    (호이스팅됨)
function Card(suit, rank) {
    this.suit = suit;
    this.rank = rank;
}
Card.prototype.show = function() {
    console.log(this.suit + this.rank)
}
  1. 함수 리터럴로 정의하는 방법
var Card = function(suit, rank) {
    this.suit = suit;
    this.rank = rank;
}
  1. 클래스 선언문으로 정의하는 방법
class Card {
    constructor(suit, rank) {
        this.suit = suit;
        this.rank = rank;
    }

    show() {
        console.log(this.suit + this.rank)
    }
}
  1. 클래스 표현식으로 정의하는 방법
var Card = class {
    constructor(suit, rank) {
        this.suit = suit;
        this.rank = rank;
    }
    show() {
        console.log(this.suit + this.rank)
    }
}

18.1.2 생성자로 접근자 프로퍼티 정의하기

프로퍼티를 특정 방법으로만 읽고 쓰도록 강제할 수 있음.(getter, setter)

function Person(name) {
    Object.defineProtperty(this, 'name', {
        get : function() {
            return name;
        },
        set : function(newName) {
            name = newName;
        },
        configurable : true,
        enumerable : true,
    })
}
Person.prototype.sayName = function() {
    console.log(this.name);
}

var person = new Person('Tom');
console.log(p.name); // Tom
p.name = 'Huck';
console.log(p.name); // Huck
p.sayName(); // Huck

18.2 생성자 상속

18.2.1 생성자 상속

자바스크립트에서는 생성자가 클래스의 역할을 함
객체의 프로토타입 상속 메커니즘을 채택
생성자 또한 객체이므로 객체의 프로토타입 상속을 활용하면 생성자 상속을 구현할 수 있음.

상속하는 생성자 : 슈퍼타입 생성자
상속받은 생성자 : 서브타입 생성자

18.2.2 슈퍼타입 생성자의 예

예제1

Ellipse생성자로 생성한 인스턴스 ellipse는 자신이 갖고있지 않는 메서드를
Ellipse.prototype과 Object.prototype에서 상속받아 사용할 수 있음

18.2.3 생성자의 prototype 상속하기

function Circle(r) {
    this.a = r;
    this.b = r;
}

var circle = new Circle(2);

circle의 프로토타입 : Circle.prototype
Circle.prototype의 프로토타입 : Object.prototype

circle에서 Ellipse.prototype을 사용하려면 Circle.prototype이 Ellipse.prototype을 상속받아야함.
-> circle의 프로토타입체인에 Ellipse.prototype을 삽입해야함

예제2

예제2-다른방법
하지만 이 방법은 Circle.prototype에 이미 생성된 Ellipse의 프로퍼티를 낭비하는 단점이 있음.

18.2.4 생성자 빌려오기

call메서드를 이용해 Ellipse 생성자에서 정의한 프로퍼티(this.a, this.b)를 Circle생성자 안에 가져오기

예제

18.2.5 슈퍼타입의 메서드 이용하기

Ellipse.prototype.toString을 덮어쓰는 방식으로, 새로정의하는것 대신에
Ellipse.prototype 메서드를 이용해서 정의함

예제

18.3 ECMAScript6의 클래스 구문

18.3.1 클래스 구문의 기본

클래스 구문의 종류

  • 클래스 선언문
  • 클래스 표현식
// 생성자
function Circle(center, radius) {
    this.center = center;
    this.radius = radius;
}

Circle.prototype.area = function() {
    return Math.PI * this.radius * this.radius;
}

// 클래스 구문
class Circle2 {
    constructor(center, radius) {
        this.center = center;
        this.radius = radius;
    }

    // prototype 메서드
    area() {
        return Math.PI * this.radius * this.radius;
    }
}

클래스 선언문 작성 방법

  • class 이름
  • 클래스의 몸통(class body) {...}에서 클래스 멤버를 정의.
    클래스 멤버는 함수선언문에서 function을 생략함
  • constructor외에 추가된 클래스멤버는 prototype에 메서드로 추가됨

클래스선언문과 함수선언문의 차이

  • 클래스 선언문의 경우 호이스팅 되지 않음. 생성자를 사용하기 전 선언되어야함
  • 한번만 작성가능. 같은 이름의 클래스 선언문은 두번작성 시 타입오류발생
  • 클래스 선언문에 정의한 생성자만 따로 호출할 수 없음

클래스 표현식

var Circle = class {
    //생성자를 이용한 초기화
    constructor(center, radius) {
        this.center = center;
        this.radius = radius;
    }
    area() {
        return Math.PI * this.radius * this.radius;
    }
}

class 다음에는 모든 식별자를 이름으로 사용할 수 있음

var Circle = class Kreis { ... }

// Kreis라는 이름은 클래스바디 내에서만 유효
var k = new Kreis() // 에러발생
var c = new Circle() // 정상적으로 인스턴스 생성됨

18.3.2 접근자 생성하기

getter와 setter 생성하기

class Person {
    constructor(name) {
        this.name = name;
    }

    get name() {
        return this._name;
    }

    set name(value) {
        this._name = value;
    }

    sayName() {
        console.log(this.name);
    }
}

get과 set키워드를 사용해서 접근자를 정의

var person = new Person('Tom');
console.log(person.name); // 'Tom'
person.name = 'Huck';
console.log(person.name); // 'Huck'
person.sayName(); // Huck
  1. name setter 프로퍼티에 값을 대입하면 _name이라는 프로퍼티가 추가되고,
    그 값을 _name에 저장함
  2. constructor의 인수인 name값을 setter인 person.name에 대입함
  3. constructor가 받은 인수 name, name접근자 프로퍼티, _name은 모두 다른 존재임
  4. getter와 setter는 모두 Person.prototype에 정의됨

18.3.3 정적 메서드 작성

static 메서드를 통해 정적메서드 작성 가능

예제

18.3.4 상속으로 클래스 확장하기

extends 키워드를 클래스 선언문이나 표현식에 사용하면 다른 생성자를 상속받을 수 있음

예제

Ball 생성자의 인스턴스가 Circle의 area와 toString이외에도 추가로 정의한 move도 사용할 수 있다.

18.3.5 슈퍼타입의 메서드 호출하기

super 키워드를 활용해 서브타입의 생성자가 슈퍼타입 생성자의 메서드를 호출할 수 있다.

super타입의메서드사용

**클래스구문은 함수를 정의한다(클래스를 정의하지 않는다)

좋은 웹페이지 즐겨찾기