Javascript "extending" 子对象或子类中的方法

Javascript "extending" a method in a sub-object or subclass

我的目标是拥有一个小部件对象并让特定的小部件扩展该对象。我想通过以某种方式在父级(Widget)中扩展它来防止人们不得不在每个小部件定义中显式调用渲染回调。实现此目标的最佳方法是什么?

 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);

除了我的评论:如果它对所有人都相同,则不必是回调函数,如果它的作业是同步的,只需将代码放在 render 方法的末尾,如果不使用承诺,但你必须考虑方法阴影,你将覆盖子项中的父 class' render 方法。为避免这种情况,您可以为方法使用不同的名称并从子级调用父级的方法或使用具有 super 关键字的 ES2015 class 来访问父级 class' 方法。

您的代码中还有一个错字:

SpecialWidget.prototype = Object.create(Widget);

必须是:

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

总的来说,我认为这不是一个好主意。

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();