方式1: 原型链继承
function Supper() { //父类型this.superProp = 'The super prop'}//原型的数据所有的实例对象都可见Supper.prototype.showSupperProp = function () {console.log(this.superProp)}function Sub() { //子类型this.subProp = 'The sub prop'}// 子类的原型为父类的实例Sub.prototype = new Supper()// 修正Sub.prototype.constructor为Sub本身Sub.prototype.constructor = SubSub.prototype.showSubProp = function () {console.log(this.subProp)}// 创建子类型的实例var sub = new Sub()// 调用父类型的方法sub.showSubProp()// 调用子类型的方法sub.showSupperProp()
特点:这种继承方式的最大特点就是共享,所有实例共享原型对象中的所有属性和方法,
**
方式2、借用构造函数继承
function Person(name, age) {this.name = namethis.age = age}Person.prototype.setAge=function(age){this.age = age}function Student(name, age, price) {Person.call(this, name, age) // this.Person(name, age)this.price = price}var s = new Student('Tom', 20, 12000)console.log(s.name, s.age, s.price)
缺点:只能继承父类实例的属性和方法,不能继承原型上的属性和方法
方式3、组合继承
function Person(name, age) {this.name = namethis.age = age}Person.prototype.setName = function (name) {this.name = name}function Student(name, age, price) {Person.call(this, name, age) //得到父类型的属性this.price = price}Student.prototype = new Person() //得到父类型的方法Student.prototype.constructor = StudentStudent.prototype.setPrice = function (price) {this.price = price}var s = new Student('Tom', 12, 10000)s.setPrice(11000)s.setName('Bob')console.log(s)console.log(s.constructor)
- 优点:可以继承实例属性/方法,也可以继承原型属性/方法
- 缺点:调用了两次父类构造函数,生成了两份实例
方式4、寄生组合继承(最优法)
function inheritPrototype(subType, superType){var protoType = Object.create(superType.prototype); //创建对象protoType.constructor = subType; //增强对象subType.prototype = protoType; //指定对象}function SuperType(name){this.name = name;this.colors = ["red", "blue", "green"];}SuperType.prototype.sayName = function(){alert(this.name);}function SubType(name, age){SuperType.call(this, name); //第二次调用SuperType()this.age = age;}// 方法1inheritPrototype(SubType, SuperType)// 方法2// SubType.prototype = Object.create(SuperType.prototype)//核心代码// SubType.prototype.constructor = SubType//核心代码SubType.prototype.sayAge = function(){alert(this.age);}var instance = new SubType("Bob", 18);instance.sayName();instance.sayAge();
inheritPrototype函数接收两个参数:子类型构造函数和超类型构造函数。
1. 创建超类型原型的副本。
2. 为创建的副本添加constructor属性,弥补因重写原型而失去的默认的constructor属性
3. 将新创建的对象(即副本)赋值给子类型的原型这种方法只调用了一次SuperType构造函数,instanceof 和isPrototypeOf()也能正常使用。
