ES6 class, super

2020. 5. 8. 17:11JavaScript

# psudoclassical instantation

 - ES6 class 키워드 등장 이전에 사용되던 방법

 - 하나의 인스턴스에 여러 개의 생성자 함수를 연결할 때, prototype 연결을 해 주는 방법으로 Object.create( ) 로 상위 생성자함수의 prototype을 하위 생성자함수의 prototype이 가리키도록 했다.

 - 하지만 위와 같은 방식으로는 하위 생성자 함수와 인스턴스의 constructor 연결이 모호해지는 문제가 생긴다.

 - 그래서 하위 생성자함수의 prototype.constructor를 다시 하위 생성자함수로 지정해주는 과정을 거쳐야 했다.

function Animal(name) {
    this.name = name;
}
Animal.prototype.eat = function(){
    console.log('먹는중');
}

function Rabbit() {}
Rabbit.prototype.run = function(){
    console.log('달리는중');
}

let whiteRabbit = new Rabbit();

 

 - whiteRabbit에서 Animal의 eat 메소드와 Rabbit의 run 메소드를 전부 사용하고 싶을 때:

 - Object.create( ) 을 이용해 Animal.prototype과 같은 새 객체를 만들어, Rabbit.prototype에 연결한다.

Rabbit.prototype = Object.create(Animal.prototype)
// Animal의 prototype을 Rabbit의 prototype이 가리키도록 만들어줌

let whiteRabbit = new Rabbit();

whiteRabbit.run();  // 달리는중
whiteRabbit.eat();  // 먹는중

whiteRabbit instanceof Rabbit;  // true
whiteRabbit instanceof Animal;  // true

 

 - 위의 과정을 거치면 인스턴스의 constructor가 Animal이 되어버리는 문제가 발생하게 된다.

console.log(whiteRabbit.__proto__);
// 결과
// constructor가 Animal이 되어버려 Rabbit과의 연결고리가 모호해짐

Rabbit.prototype.constructor = Rabbit;
// constructor를 인위적으로 다시 Rabbit으로 지정

console.log(whiteRabbit.__proto__);
// 결과

 

constructor를 지정해주기 전: constructor가 Animal

 

constructot를 지정해준 후: constructor가 Rabbit

 

 - 인스턴스의 컨텍스트(this값 포함)가 상위 클래스들에 전달이 되지 않는 문제 역시 해결해야 한다.

function Animal(name) {
    this.name = name;
}
Animal.prototype.eat = function(){
    console.log(`${this.name}는 먹는중`);
}

function Rabbit(name) {}

Rabbit.prototype = Object.create(Animal.prototype);
Rabbit.prototype.constructor = Rabbit;

let whiteRabbit = new Rabbit('흰토끼');

whiteRabbit.eat(); // undefined는 먹는중

 

 - call, apply 메소드를 사용해 하위 클래스에서 상위 클래스로 this를 전달해 줘야 한다.

function Animal(name) {
    this.name = name;
}
Animal.prototype.eat = function(){
    console.log(`${this.name}는 먹는중`);
}

function Rabbit(name) {
    Animal.call(this, name);
    // 혹은 Animal.apply(this, arguments)
}

Rabbit.prototype = Object.create(Animal.prototype);
Rabbit.prototype.constructor = Rabbit;

let whiteRabbit = new Rabbit('흰토끼');

whiteRabbit.eat(); // 흰토끼는 먹는중

 

 

# class

 - 하지만 ES6에서 class 등장 이후로, 위의 과정들을 class, constructor, super, extends를 이용해 더욱 직관적으로 표현할 수 있게 되었다.

class Animal {
    constructor(name) {
        this.name = name;
    }    
    eat() {
        console.log(`${this.name}는 먹는중`);
    }
}

class Rabbit extends Animal{
    constructor(name) {
        super(name);
    }
    run() {
        console.log('달리는중');
    }
}

let whiteRabbit = new Rabbit('흰토끼');

whiteRabbit.eat();  // 흰토끼는 먹는중
whiteRabbit.run();  // 달리는중

 

 - Animal class를 만든 뒤, extends 키워드를 이용해 Animal class의 하위 class가 되는 Rabbit class를 만들었다.

 - Rabbit class는 constructor 안에서 super 키워드를 통해서, 부모 class인 Animal에서 name 속성을 가져오고 있다.

 

 

 

 

 

'JavaScript' 카테고리의 다른 글

200611 TIL :: Promise  (0) 2020.06.09
Object Oriented Programming  (0) 2020.05.08
Closure  (0) 2020.04.28
이벤트 버블링과 캡쳐  (0) 2020.03.26
function method, this  (0) 2020.03.18