Class

생성자함수 예시

지금까지 비슷한 형태의 객체를 생성하기 위해서 생성자 함수를 이용했다.

const User = function(name, age){
    this.name = name;
    this.age = age;
    this.showName = function(){
        console.log(this.name);
    };
}

const mike = new User("Mike", 30);


Class 사용

하지만 ES6부터 추가된 Class를 사용하여 만들수도 있다.

class User2{
    constructor(name, age){
        this.name = name;
        this.age = age;
    }
    showName(){
        console.log(name);
    }
}

const tom = new User2("Tom", 19);
  1. new를 통해서 호출했을 때 내부에서 정의된 내용으로 객체를 생성하는 것은 동일하다.
  2. class라는 키워드를 사용하고, 내부에 constructor가 있다.constructor는 객체를 만들어주는 생성자 메소드이다.
  3. this가 포함된 문장은 객체를 초기화하기 위한 값
  4. showName처럼 class내에 정의한 메소드는 User2의 프로토타입에 저장된다.
  5. 따라서 Mike는 객체 내부에 showName이 있고 Tom은 프로토타입 내부에 showName이 있다.(사용법은 동일)


생성자함수와 Class의 비교

생성자함수에서 class와 동일하게 작용하려면

const User = function(name, age){
    this.name = name;
    this.age = age;
}

User.prototype.showName = function(){
    console.log(this.name);
}

const mike = new User("Mike", 30);

생성자함수에서는 new를 빼고 실행해도 실행은 된다. undefined
class를 사용하면 new없이 실행될 수 없다는 에러가 발생한다. 즉, 에러를 찾을 수 있기 때문에 class를 이용하는게 유리하다.

tom과 mike의 프로토타입 내부에 있는 constructor을 보면 tom의 constructor은 class라는 것을 확인할 수 있고 이 경우에 new없이 호출하면 에러가 발생된다.



for in문

for (const p in mike) {
    console.log(p);
} // name / age / showName

for (const p in tom) {
    console.log(p);
} // name / age  

for in문은 프로토타입에 포함된 프로퍼티를 다 보여주고 객체가 가진 프로퍼티만 판별하기 위해서 hasOwnPropety 사용해야 했지만 class의 메소드는 for in문에서 제외된다.



Class 상속

생성자함수의 경우 prototype을 이용했었지만 class에서는 extends를 사용한다.

class Car{
    constructor(color){
        this.color = color;
        this.wheels = 4;
    }
    drive(){
        console.log("drive..");
    }
    stop(){
        console.log("STOP!");
    }
}

class Bmw extends Car{
    park(){
        console.log("PARK");
    }
}

const z4 = new Bmw("blue");


method overriding

만약 Bmw 내부에 Car에서 정의한 메소드와 동일한 이름의 메소드가 있다면

class Car{
    constructor(color){
        this.color = color;
        this.wheels = 4;
    }
    drive(){
        console.log("drive..");
    }
    stop(){
        console.log("STOP!");
    }
}

class Bmw extends Car{
    park(){
        console.log("PARK");
    }
    stop(){
        console.log("stop");
    }
}

const z4 = new Bmw("blue");

z4.stop(); // stop

동일한 이름으로 상용하면 덮어쓰이게 된다.

만약 부모의 이름을 그대로 사용하면서 확장하고 싶다면 super라는 키워드를 사용하면 된다.

class Car{
    constructor(color){
        this.color = color;
        this.wheels = 4;
    }
    drive(){
        console.log("drive..");
    }
    stop(){
        console.log("STOP!");
    }
}

class Bmw extends Car{
    park(){
        console.log("PARK");
    }
    stop(){
        super.stop();
        console.log("stop");
    }
}

const z4 = new Bmw("blue");

z4.stop(); // STOP! / stop

이렇게 super를 사용하여 부모 class의 메소드를 사용하는 방식을 메소드 오버라이딩이라고 한다.



constructor overrinding

constructor을 만들어서 navigation 추가

class Car{
    constructor(color){
        this.color = color;
        this.wheels = 4;
    }
    drive(){
        console.log("drive..");
    }
    stop(){
        console.log("STOP!");
    }
}

class Bmw extends Car{
    constructor(){
        this.navigation = 1;
    }
    park(){
        console.log("PARK");
    }
    stop(){
        super.stop();
        console.log("stop");
    }
}

const z4 = new Bmw("blue");

constuctor에서 this를 사용하기 전에 super.constuctor 즉, 부모 constructor을 반드시 생성해야 한다는 에러이다.

class Car{
    constructor(color){
        this.color = color;
        this.wheels = 4;
    }
    drive(){
        console.log("drive..");
    }
    stop(){
        console.log("STOP!");
    }
}

class Bmw extends Car{
    constructor(color){
        super(color);
        this.navigation = 1;
    }
    park(){
        console.log("PARK");
    }
    stop(){
        super.stop();
        console.log("stop");
    }
}

const z4 = new Bmw("blue");

console.log(z4);

또한 부모와 동일한 인수를 받는 작업을 해야한다. (color)

댓글남기기