构造函数,原型,实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,实例都包含一个指向原型对象的内部指针。
原型链:一个对象的原型等于另一个对象的实例,此时原型对象将包含一个指向另一个原型的指针,层层递进,构成了实例与原型之间的链条,这就是原型链。
继承:依靠原型链来实现的。
原型链继承
很少单独使用
缺点:最主要的问题来自包含引用类型值的原型会被所有实例共享;创建子类型的实例时,不能向超类型传递参数1234567891011function SuperType(){this.colors = ['red', 'blue', 'green'];}function SubType(){}SubType.protoype = new SuperType();var instance1 = new SubType();instance1.colors.push('black');console.log('colors', instance1.colors); //['red', 'blue', 'green', 'black']var instance2 = new SubType();console.log('colors', instance2.colors); //['red', 'blue', 'green', 'black'](经典继承)借用构造函数继承
很少单独使用
在子类构造函数的内部调用超类构造函数,解决引用类型共享的问题;可传递参数
缺点:无法实现函数的复用123456789101112function SuperType(name){this.name = name;this.colors = ['red', 'blue', 'green'];}function SubType(){SuperType.call(this, name);}var instance1 = new SubType();instance1.colors.push('black'); //['red', 'blue', 'green', 'black']console.log(instance1);var instance2 = new SubType();console.log(instance2);组合继承(原型链和借用构造函数的组合)
将原型链和借用构造函数的技术组合到一块,使用原型链实现对原型属性和方法的继承,通过借用构造行数来实现对实例属性的继承,既通过在原型上定义方法实现了函数复用,又能保证每个实例儿都有自己的属性
常用的继承模式
缺点: 无论什么情况下,都会调用两次超类型构造函数原型式继承(同ECMAScript的Object.create)
基于已有的对象,借助原型创建新对象
应用场景:只想让一个对象与另一个对象保持类似的情况下。
缺点:包含引用类型的值会共享12345```5. 寄生式继承创建一个仅用于封装继承过程的函数,任何能够返回新对象的函数都适用于此模式缺点:不能做到函数的复用```javascript寄生组合式继承
最常用的继承模式
借用构造函数来继承属性,通过原型链来继承方法。
与组合式继承相比,它只调用了一次SuperType构造行数,并且因此避免了在SubType.prototype上创建不必要的,多余的属性。寄生组合式继承是引用类型最理想的继承方式