这篇文章主要介绍“JS继承、工厂构造及原型设计模式实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“JS继承、工厂构造及原型设计模式实例分析”文章能帮助大家解决问题。
正文
正是由于:原型链继承和构造函数继承的 “毛病”
原型链继承:所有继承的属性和方法都会在对象实例间共享,无法做到实例私有。
构造函数继承:子类不能访问父类原型上的方法。
组合继承应运而生:
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"];}function SubType(name, age){ SuperType.call(this, name) // 构造函数继承 (两次调用父类构造函数) this.age = age;}SuperType.prototype.sayName = function() { console.log(this.name);}SubType.prototype = new SuperType() // 原型链继承 (一次调用父类构造函数)SubType.prototype.sayAge = function() { console.log(this.age);}let s1 = new SubType("Nicholas", 29)let s2= new SubType("Greg", 27)s1.colors.push("yellow")console.log(s1.colors) // ['red', 'blue', 'green', 'yellow']console.log(s2.colors) // ['red', 'blue', 'green']s1.sayName() // Nicholass2.sayName() // Gregs1.sayAge() // 29s2.sayAge() // 27
但是呢?这样做,会有效率问题,父类构造函数始终会被调用两次:一次是在子类构造函数中调用,另一次在是创建子类原型时调用。
本质上,子类原型最终是要包含超类对象的所有实例属性,子类构造函数只要在执行时重写自己的原型就行了。
这个时候有一个新的思路!
不通过调用父类构造函数给子类原型赋值,而是取得父类原型的一个副本。使用寄生式继承来继承父 类原型,然后将返回的新对象赋值给子类原型。
核心代码是:通过工厂的方式,增强一个新对象:
function createAnother(original){ let clone = Object(original); // 通过调用函数创建一个新对象 clone.sayHi = function() { // 以某种方式增强这个对象 console.log("hi"); }; return clone; // 返回这个对象}
将组合代码改造一下,完整代码是:
function inheritPrototype(subType, superType) { let prototype = Object(superType.prototype); // 创建对象 prototype.constructor = subType; // 增强对象 subType.prototype = prototype; // 赋值对象}function SuperType(name) { this.name = name; this.colors = ["red", "blue", "green"];}function SubType(name, age) { SuperType.call(this, name); // 构造函数继承(只调了一次) this.age = age;}SuperType.prototype.sayName = function() { console.log(this.name);};inheritPrototype(SubType, SuperType); // 寄生继承SubType.prototype.sayAge = function() { console.log(this.age);};let s1 = new SubType("Nicholas", 29)let s2= new SubType("Greg", 27)s1.colors.push("yellow")console.log(s1.colors) // ['red', 'blue', 'green', 'yellow']console.log(s2.colors) // ['red', 'blue', 'green']s1.sayName() // Nicholass2.sayName() // Gregs1.sayAge() // 29s2.sayAge() // 27
这里只调用了一次 SuperType 构造函数,避免了 SubType.prototype 上不必要也用不到的属性;而且,原型链仍然保持不变,instanceof 操作符和 isPrototypeOf() 方法正常有效。
寄生式组合继承可以算是【引用类型】继承的最佳模式
os:不过这里的增强写法,理解起来真是怪,为什么父类的显示原型的构造函数等于子类?
SuperType.prototype.constructor=== SubType // true
大概是为了,通过寄生实现:父类、子类都由同一函数构造;
SubType === SubType.prototype.constructor // trueSuperType.prototype.constructor === SubType.prototype.constructor // true
关于“JS继承、工厂构造及原型设计模式实例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。