Как сохранить ссылку на себя в супер-конструкторе?

Рейтинг: 0Ответов: 1Опубликовано: 31.10.2014
var Super = ( function( ){
    function Super( args ){
        this.init( args );
    }

    Super.prototype = {
        name: undefined,
        constructor: Super,
        init: function( args ){
            this.name = args.name;
        },
        toString: function( ){
            return this.name;
        }
    };

    return Super;
}( ) );

var Sub = ( function( SUPER ){
    function Sub( args ){
        SUPER.call( this, args );
    }

    Sub.prototype = Object.create( SUPER.prototype );
    Sub.prototype.constructor = Sub;

    Sub.prototype.init = function( args ){

    };

    return Sub;
}( Super ) );

var subOne = new Sub( {name: 'sub_1'} );

Возможно ли как-то сохранить ссылку на себя в объекте Super, для того чтобы не заниматься копипастом при переопределении методов в потомках?

Добавлено:

Или это самое время для приватных областей? Если делать так, то это не будет считаться нехорошо?

var Super = ( function( ){
    var _context,
    _init = function( args ){
        _context.name = args.name;
    };

    function Super( args ){
        // this.init( args );
        _context = this;
        _init( args );
    }

    Super.prototype = {
        name: undefined,
        constructor: Super,
        super: Object,
        toString: function( ){
            return this.name;
        }
    };

    return Super;
}( ) );

var Sub = ( function( SUPER ){
    var _context,
    _init = function( args ){
        // ...
    };

    function Sub( args ){
        SUPER.call( this, args );
        _context = this;
        _init( args );
    }

    Sub.prototype = Object.create( SUPER.prototype );
    Sub.prototype.constructor = Sub;
    Sub.prototype.super = SUPER;

    return Sub;
}( Super ) );

var subOne = new Sub( {name: 'sub_1'} );
var subTwo = new Sub( {name: 'sub_2'} );

console.log( subOne.toString( ), subTwo.toString( ) ); // sub_1 sub_2

Ответы

▲ 2Принят

Реализация super/parent - это философский камень в мире JS, эликсир вечного холивара, количество реализаций просто зашкаливает, а ответа тут только два:

ES5 Native

/** @class Hello */
var Hello = function () {
    this.text = ["Hello"]
};

Hello.prototype.toString = function () {
    return this.text.join(' ');
};

/** @class HelloJS @extends Hello */
var HelloJS = function () {
    // Вызываем родительский конструктор
    Hello.call(this);
    this.text.push('JS');
};

// Наследуем Hello
HelloJS.prototype = Object.create(Hello.prototype);

// Переопределяем метод
HelloJS.prototype.toString = function () {
    // Вызываем родительский метод
    var text = Hello.prototype.toString.call(this);
    return text + '!';
};

// Используем
var hello  = new Hello;
var helloJS  = new HelloJS;
console.log(hello + '', [hello instanceof Hello]); // "Hello", [true]
console.log(helloJS + '', [helloJS instanceof Hello, helloJS instanceof HelloJS]); // "Hello JS!", [true, true]

ES6

class Hello {
    constructor() {
        this.text = ["Hello"];
    },

    toString() {
        return this.text.join(' ');
    }
};

class HelloJS extends Hello {
    constructor() {
        this.super();
        this.text.push('JS');
    },

    toString() {
        var text = this.super()
        return text + '!';
    }
};

P.S. Либо TS, CS и другие *Script.