说明:本文仅是笔记
一、原型链继承
// 将父类的实例赋给子类的原型
function superType() {
this.property = true
}
superType.prototype.getSuperType = function() {
return this.property
}
function subType() {}
// 创建父类的实例赋给子类原型
subType.prototype = new superType()
var insance = new subType()
console.log(insance.getSuperType()); // true
// instance.__proto__ = subType.prototype -> subType.prototype.__proto__ = superType.prototype
// 缺点:多个实例共享引用类型,当引用类型发生改变,所有实例都有受到影响
二、借用构造函数继承
// 使用父类构造函数增强子类实例
function superType() {
this.arr = [1,2,3]
}
function subType() {
superType.call(this)
}
const instance1 = new subType()
instance1.arr.push(4)
console.log(instance1.arr); // [ 1, 2, 3, 4 ]
const instance2 = new subType()
console.log(instance2.arr); // [ 1, 2, 3 ]
// 子类的每个实例都会将父类的属性复制一份,无法实现复用
// 不能继承父类原型的方法和属性
三、组合继承
// 组合上面两种方法就是组合继承,原型链继承父类原型的属性和方法
// 构造函数实现对父类内部属性和方法的继承
function superType() {
this.superName = 'superName'
}
superType.prototype.getSuperName = function() {
return this.superName
}
function subType(name,age) {
// 子类创建实例时再次调用superType
superType.call(this)
this.name = name
this.age = age
}
// 第一次调用superType
subType.prototype = new superType()
subType.prototype.constructor = subType
const instance = new subType('XiaoMing',12)
console.log(instance.age); // 12
console.log(instance.name); // XiaoMing
console.log(instance.getSuperName()); // superName
// 子类实例中会存有两份父类内部的属性和方法(不包括原型上的属性和方法)
四、原型式继承
// 利用空对象作为中介 将对象复制给空对象构造函数的原型
function object(obj) {
function F() {}
F.prototype = obj
return new F()
}
var person = {
arrs: []
}
var instance1 = object(person)
instance1.arrs.push(1)
var instance2 = object(person)
instance2.arrs.push(2)
console.log(person.arrs); // [ 1, 2 ]
// 引用类型被多个实例共享,发生改变会影响所有实例
// 不能传递参数
// 存在Object.create()方法可以替代上面的object函数
五、寄生式继承
// 在原型式继承的基础上 增强对象
function object(obj) {
function F() {}
F.prototype = obj
return new F()
}
function create(original) {
var clone = object(original)
clone.sayHi = function() {
console.log('Hi');
}
return clone
}
var person = {
name: 'XiaoMing'
}
var instance1 = create(person)
instance1.sayHi() // Hi
console.log(instance1.name); // XiaoMing
六、寄生式组合继承
// 结合借用构造函数传递参数和寄生模式实现原型链继承
// 相对于组合继承 子类中对父类内部的变量和函数只继承一次
// 这是最成熟的方法
function inheritProperty(subType, superType) {
// prototype.__proto__ = superType.prototype
var prototype = Object.create(superType.prototype)
prototype.constructor = subType
subType.prototype = prototype
}
function superType() {
this.superName = 'superName'
}
superType.prototype.getSuperName = function() {
return this.superName
}
function subType(name) {
superType.call(this)
this.subName = name
}
// 将父类原型指向子类
inheritProperty(subType, superType)
// 新增子类原型属性
subType.prototype.getSubName = function() {
return this.subName
}
let instance = new subType('XiaoMing')
console.log(instance.getSuperName()) // superName
console.log(instance.getSubName()) // XiaoMing
七、ES6继承extends
class Rectangle {
constructor(height,width) {
this.height = height
this.width = width
this.name = 'Rectangle'
}
getArea() {
return this.height * this.width
}
}
class Square extends Rectangle {
constructor(length) {
super(length, length)
// 子类使用this前需要先调用super()
this.name = 'Square'
}
}
let instance = new Square(40)
console.log(instance.getArea()); // 1600
console.log(instance.name); // Square