본문 바로가기

자바스크립트

객체지향 프로그래밍(3) : 클래스기반 상속

function Person(arg) {
    this.name = arg;
}

Person.prototype.setName = function(value) {
    this.name = value;
}

Person.prototype.getName= function() {
    return this.name;
}

function Student(arg) {}

var you = new Person('dev-jones');
Student.prototype = you;

var me = new Student('grindman');
me.setName('grindman');
console.log(me.getName());

me 인스턴스를 생성할 때 부모 클래스인 Person의 생성자를 호출하지 않는다.

var me = new Student('grindman');

Student 함수에 다음 코드를 추가하여 부모 클래스의 생성자를 호출해야한다.

function Student(arg) {
    Person.apply(this, arguments);
}

Student 함수 안에서 새롭게 생성된 객체를 apply 함수의 첫 번째 인자로 넘겨 Person 함수를 실행시킨다. 이런 방식으로 자식 클래스이 인스턴스에 대해서도 부모 클래스의 생성자를 실행시킬 수 있다. 클래스 간의 상속에서 하위 클래스의 인스턴스를 생성할 때, 부모 클래스의 생성자를 호출해야 하는데, 이 경우에 필요한 방식이다.

 

위 코드는 자식 클래스의 객체가 부모 클래스의 객체를 프로토타입 체인으로 직접 접근한다. 하지만 부모 클래스의 인스턴스와 자식 클래스의 인스턴스는 서로 독립적일 필요가 있다.

function Person(arg) {
    this.name = arg;
}

Function.prototype.method = function(name, func) {
    this.prototype[name] = func;
}

Person.method('setName', function(value) {
    this.name = value;
});
Person.method('getName', function() {
    return this.name;
});

function Student(arg) {
}

function F() {};
F.prototype = Person.prototype;
Student.prototype = new F();
Student.prototype.constructor = Student;
Student.super = Person.prototype;

var me = new Student();
me.setName('grindman');
console.log(me.getName());

빈 함수의 객체를 중간에 두어 Person의 인스턴스와 Student의 인스턴스를 서로 독립적으로 만들었다. 이제 Person 함수 객체에서 this에 바인딩되는 것은 Student의 인스턴스가 접근할 수 없다.

var inherit = function(Parent, Child) {
    var F = function() {};
    return function(Parent, Child) {
        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor = Child;
        Child.super = Parent.prototype;
    }
}

클로저는 F() 함수를 지속적으로 참조하므로, F()는 가비지컬렉션의 대상이 되지 않고 계속 남아있다. 이를 이용해 함수 F()의 생성은 단 한 번 이루어지고 inherit 함수가 계속해서 호출되어도 함수 F()의 생성을 새로 할 필요가 없다.