ES5 寄生式继承
Posted ltfxy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES5 寄生式继承相关的知识,希望对你有一定的参考价值。
3 寄生式继承
- 组合继承存在调用两次父类构造的问题
- 原型继承存在不能实例化对象不能传参的问题
- 组合继承和原型继承都存在子类原有原型属性被覆盖的问题
- 因此推荐使用寄生式继承
/* 寄生式继承: 1 解决子类原型对象属性被覆盖的问题: 设置F.property接收父类原型属性,将子类原型属性复制到F.property 再将复制了子类原型属性的F.peoperty设置给子类原型完成属性的覆盖 2 解决调用父类构造问题: 将父类当成属性设置到子类的原型上,子类实例对象就可以在原型链上找到父类构造函数, 子类可以通过this调用自身方法实现实例化,不通过调用外面父类的构造函数传参 这样即实现了功能,又避免了组合继承调用父类构造次数过多和原型继承实例化无法通过构造传参的问题 */ function Box(_r) { //设置Box类实例化对象的属性 this.r = _r; console.log("constructor run"); } Box.a = 3; Box.run = function () { console.log(Box.a); } Box.prototype = { b: 10, play: function () { } } function Ball(_r) { this.supClass.apply(this, arguments); } Ball.prototype.walk = function () { console.log("walk"); } extend(Ball, Box); Ball.prototype.play = function () { this.supClass.prototype.play.apply(this.arguments); console.log("finish method"); } var b = new Ball(10);//print constructor run b.play(); // print finish method console.log(b); function extend(subClass, supClass) { function F() { } //将子类原型属性覆盖掉父类原型相同的属性,再设置给子类 F.prototype = supClass.prototype; //复制原来原型下的内容 if (Object.assign) { //Objec.asssign不兼容IE Object.assign(F.prototype, subClass.prototype); } else { if (Object.getOwnPropertyNames) { var names = Object.getOwnPropertyNames(subClass.prototype); for (var i = 0; i < names.length; i++) { Object.defineProperty(F.prototype, name[i], Object.getOwnPropertyDescriptor(names[i])); } } else { for (var prop in subClass.prototype) { F.prototype[prop] = subClass.prototype[prop]; } } } //完成属性覆盖 subClass.prototype = new F(); //将子类构造设置为自身,不调用外面父类的构造 subClass.prototype.constructor = subClass; //父类设置到子类原型上去以供this调用 subClass.prototype.supClass = supClass; if (supClass.prototype.constructor === Object) { supClass.prototype.constructor = supClass; } }
执行结果:
以上是关于ES5 寄生式继承的主要内容,如果未能解决你的问题,请参考以下文章
JavaScript ----------------- 寄生式继承
JSJavaScript继承 - 原型链 - 盗用构造函数 - 组合继承 -原型式继承 - 寄生式继承 - 寄生式组合继承
JavaScript之面向对象学九(原型式继承和寄生式继承)