我们都听说过JavaScript语言是可以实现多种方式的继承,比如原型链继承、工厂模式中的构造函数继承等。但是上面这些继承方式虽然都能达到继承的效果,但是想要让继承工程化那还是有点美中不足的地方。今天我们就来上一盘来自雅虎前端工程师研制的既显得高大上,又不失礼节的高级承继模式。
var inherit = (function () { function Middleware () {}; return function (Target, Origin) { Middleware.prototype = Origin.prototype; Target.prototype = new Middleware; Target.prototype.constructor = Target; Target.prototype.forcefather = Origin; } }) ();
今天终于发现上面的继承方式有小缺陷,所以下面做一个改良… (2019-07-07)
var inherit = (function () { function Middleware () {}; return function (Target, Origin) { var protoTemp = Target.prototype; Middleware.prototype = new Origin(); Target.prototype = new Middleware(); Target.prototype.constructor = Target; Target.prototype.superfather = Origin; for (var key in protoTemp) { Target.prototype[key] = protoTemp[key]; } } }())
终于在ECMAScript经过十余载的努力终于规划了上一代对象之间继承的松散写法。为什么这么说?因为上面的方法只是在众多方法中抽取出来近乎完美的方案,十个人可能就有六种不同的写法,这在协助开发当中是极其不利的。下面来看看ECMAScript6版新出的规范继承的写法。
class Person { constructor (name, age, sex) { this.name = name; this.age = age; this.sex = sex; } sayName () { console.log(this.name); } } class Student extends Person { constructor (name, age, sex, job) { super(name, age, sex); this.job = job; } sayAge () { console.log(this.age); } } var p = new Person('人类', 100, '男'); var s = new Student('学生', 18, '男', '上学'); p.sayName() // '人类' s.sayName() // '人类' p.sayAge() // undefined s.sayAge() // '学生'
上面的写法实现了 Student 继承了 Person 上所有的方法,当 Person 修改原型上的属性和方法时,Student 会实时继承下来;反之,则不会。这就是继承的原则。
这几天又一激动搞出来一个即看起来简单明了,而且又很容易理解的继承方案不妨写出来瞧瞧。。。我们现在定义两个构造函数Test1和Test2,让Test2继承Test1的属性和方法。
function Test1 (attr1) { this.attr1 = '值1'; }; Test1.prototype.handle1 = function () { console.log('执行了若干个结果Test1'); } function Test2 (attr2) { // 此步骤实现继承Test1所有的属性 Test1.call(this); this.attr2 = '值2'; }; Test2.prototype.handle2 = function () { console.log('执行了若干个结果Test2'); } // 此步骤实现原型上所有方法的继承 for (var prop in Test1.prototype) { Test2.prototype[prop] = Test1.prototype[prop]; } // 实例化两个对象看结果 var obj1 = new Test1(); var obj2 = new Test2(); // PS: 修改Test1中的属性和方法,会完全被Test2继承,反之则不会。
发表评论