将构造函数的原型设置为另一个构造函数的实例对象,这样就可以继承另一个原型对象的所有属性和方法,可以继续往上,最终形成原型链。
第一个问题是,当实现继承后,另一个原型的实例属性,变成了现在这个原型的原型属性,然后该原型的引用类型属性会被所有的实例共享,这样继承原型引用类型属性的实例之间不再具有自己的独特性了。
第二个问题是,在创建子类型的实例时,没有办法在不影响所有对象实例的情况下给超类型的构造函数中传递参数。
为了解决原型中包含引用类型值的问题,开始使用借用构造函数,也叫伪造对象或经典继承
function SuperType() { this.colors = ["red", "blue", "green"]; } function SubType() { //继承SuperType SuperType.call(this); } var instance1 = new SubType(); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" var instance2 = new SubType(); alert(instance2.colors); //"red,blue,green"存在的问题就是,所有的类型都只能使用构造函数模式(因为超类型的原型中定义的方法对于子类型不可见),因此方法都在构造函数中定义,函数复用就无从谈起了。
也叫伪经典继承,将原型链和借用构造函数的技术组合到一块。使用原型链实现对原型属性和方法的继承,而通过构造函数来实现对实例属性的继承。
实例属性定义在构造函数中,而方法则定义在构造函数的新原型中,同时将新原型的constructor指向构造函数。
可以通过instanceof和isPrototypeOf()来识别基于组合继承创建的对象。
避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为JS中最常用的继承模式。
不自定义类型的情况下,临时创建一个构造函数,借助已有的对象作为临时构造函数的原型,然后在此基础实例化对象,并返回。
本质上是object()对传入其中的对象执行了一次浅复制
其实就是在原型式继承得到对象的基础上,在内部再以某种方式来增强对象,然后返回。
思路与寄生构造函数和工厂模式类似。
新的对象中不仅具有original的所有属性和方法,而且还有自己的sayHi()方法。
寄生式继承在主要考虑对象而不是自定义类型和构造函数的情况下非常有用。
由于寄生式继承为对象添加函数不能做到函数复用,因此效率降低。
组合继承是JS中最常用的继承模式,但其实它也有不足,组合继承无论什么情况下都会调用两次超类型的构造函数,并且创建的每个实例中都要屏蔽超类型对象的所有实例属性。
寄生组合式继承就解决了上述问题,被认为是最理想的继承范式。