简体   繁体   中英

Javascript “extending” a method in a sub-object or subclass

My goal is to have a widget object and have specific widgets extend that object. I would like to prevent people from having to call the render callback explicitly in every widget definition by somehow extending it in the parent (Widget). What is the best way to accomplish this?

 var Widget = function (options) {

    // super class

    if (this.constructor === Widget) {
        throw new Error("You can't instantiate abstract class.");
    }

    var widget = this.__proto__;

    Widget.renderCallBack = function(){
        //alert('the widget has rendered');
    }

    this.render = (function(){
        var _render = this.render;

        return function(){
            _render();
            Widget.renderCallBack();
        }

    })


}
Widget.constructor = Widget;


var SpecialWidget = function(options) {
    Widget.apply(this, arguments);
}

SpecialWidget.prototype = Object.create(Widget);
SpecialWidget.constructor = SpecialWidget

SpecialWidget.prototype.render = function(){
    // render something
}

new SpecialWidget(options);

In addition to my comment: If it is the same for all it doesn't have to be a callback function, just put the code to the end of the render method if it's job is synchronous, if not use a promise but you have to think about that of method shadowing you will overwrite the parent class' render method in the child. To avoid this you can use different name for the methods and call the parent's method from the child or use ES2015 class which has the super keyword for reaching the parent class' methods.

Also you had a typo in your code:

SpecialWidget.prototype = Object.create(Widget);

It has to be:

SpecialWidget.prototype = Object.create(Widget.prototype);

Anyway I don't think it is a good idea in general.

 var Widget = function(options) { this.options = options || {}; }; Widget.prototype.widgetRender = function() { // do stuff console.log('Widget render'); // callback functionality console.log('Widget render callback functionality'); }; Widget.constructor = Widget; var SpecialWidget = function(options) { Widget.apply(this, arguments); }; SpecialWidget.prototype = Object.create(Widget.prototype); SpecialWidget.prototype.render = function() { // parent's render this.widgetRender(); // do stuff console.log('SpecialWidget render'); // callback functionality console.log('SpecialWidget render callback functionality'); }; SpecialWidget.constructor = SpecialWidget var sw = new SpecialWidget(); sw.render(); // ES2015 class ES6Widget { constructor(options) { this.options = options || {}; } render() { // do stuff console.log('ES6Widget render'); // callback functionality console.log('ES6Widget render callback functionality'); } } class ES6SpecialWidget extends ES6Widget { render() { // parent's render super.render(); // do stuff console.log('ES6SpecialWidget render'); // callback functionality console.log('ES6SpecialWidget render callback functionality'); } } const es6sw = new ES6SpecialWidget(); es6sw.render(); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM