Open AwakenedSomeone opened 3 years ago
结合之前说的对象委托,以及另一篇《重学ES6:继承的几种方式》里寄生组合继承的方式来说明。 1.首先,如果是寄生组合继承,涉及到需要调用父类(相当于Class里的supper构造函数调用),然后再通过Object.create(),让子类继承到父类。这样的方式,允许我们在子类中重写父类的方法,营造出了一种伪多态的现象。我们在构造这样的设计模式时,允许我们在原型链上有同名方法。 以编写一个控件生成对象为例:
// 类 控件 // 父类 function Widget (w, h) { this.width = w || 50 this.height = h || 50 this.$elem = null } Widget.prototype.render = function ($where) { if (this.$elem) { this.$elem.css({ width: this.width + 'px', height: this.height + 'px' }).appendTo($where) } } // 子类 function Button (w, h, label) { // 类似调用“supper”构造函数 实现寄生组合继承的关键 Widget.call(this, w, h) this.label = label || 'Default' this.$elem = $("<button>").text(this.label) } // 让Button继承Widget 实现寄生组合继承的关键 Button.prototype = Object.create(Widget.prototype) // 重写render Button.prototype.render = function ($where) { // supper 调用 Widget.prototype.render.call(this, $where) this.$elem.click(this.onClick.bind(this)) } Button.prototype.onClick = function (evt) { console.log("Botton" + this.label + "clicked") } // 实际生成的地方 $(document).read(function () { var $body = $(document.body) var btn1 = new Button(125, 30, "Hello") var btn2 = new Button(150, 40, "World") btn1.render($body) btn2.render($body) })
var Widget = { init: function (width, height) { this.width = width || 50; this.height = height || 50; this.$elem = null; }, insert: function ($where) { if (this.$elem) { this.$elem.css({ width: this.width + "px", height: this.height + "px" }).appendTo($where); } } }; var Button = Object.create(Widget); // 另写了一个setup来调用原型链上的init函数 Button.setup = function (width, height, label) { // 委托调用 this.init(width, height); this.label = label || "Default"; this.$elem = $("<button>").text(this.label); }; Button.build = function ($where) { // 委托调用 this.insert($where); this.$elem.click(this.onClick.bind(this)); }; Button.onClick = function (evt) { console.log("Button '" + this.label + "' clicked!"); }; $(document).ready(function () { var $body = $(document.body); var btn1 = Object.create(Button); btn1.setup(125, 30, "Hello"); var btn2 = Object.create(Button); btn2.setup(150, 40, "World"); btn1.build($body); btn2.build($body); });
在这本书中,作者更推崇这样的设计模式,这样语义更清楚,也不会像模仿类的方式那样复杂。我个人也更喜欢对象委托模式,这样的模式跟vue里的写法类似,更符合平常的使用风格。
结合之前说的对象委托,以及另一篇《重学ES6:继承的几种方式》里寄生组合继承的方式来说明。 1.首先,如果是寄生组合继承,涉及到需要调用父类(相当于Class里的supper构造函数调用),然后再通过Object.create(),让子类继承到父类。这样的方式,允许我们在子类中重写父类的方法,营造出了一种伪多态的现象。我们在构造这样的设计模式时,允许我们在原型链上有同名方法。 以编写一个控件生成对象为例:
在这本书中,作者更推崇这样的设计模式,这样语义更清楚,也不会像模仿类的方式那样复杂。我个人也更喜欢对象委托模式,这样的模式跟vue里的写法类似,更符合平常的使用风格。