原型链继承
// 1.原型链继承(将父类的实例作为子类的原型)
function Parent() {
this.show = true
this.info = {
name: 'xiaoye',
age: 18
}
}
Parent.prototype.getInfo = function() {
console.log(this.info, this.show)
}
function Child() {}
Child.prototype = new Parent()
let child1 = new Child()
child1.info.gender = "男"
child1.getInfo() // {name: 'ywl', age: 18, gender: '男'}
let child2 = new Child()
child2.getInfo() // {name: 'ywl', age: 18, gender: '男'}
child2.show = false
console.log(child2.show) // false
console.log(child1.show) // true
优点:
1.父类的方法可以复用
缺点:
1.父类的引用属性会被所有子类共享,更改一个父类的引用属性,其它子类也会受影响
2.子类型实例不能给父类型构造函数传参
构造函数继承
function Parent() {
this.info = {
name: 'xiaoye',
age: '18'
}
}
function Child() {
// 改变Parent构造函数this指向,复制构造函数中属性与方法
Parent.call(this)
}
let child1 = new Child()
child1.info.job = 'web'
let child2 = new Child()
console.log(child1.info) // {name: 'xiaoye', age: '18', job: 'web'}
console.log(child2.info) // {name: 'xiaoye', age: '18'}
优点:
1.父类引用属性不会被子类共享
2.可以向父类构造函数进行传参
缺点
1.不能继承父类原型上的方法(即不能访问Parent.prototype上定义的方法),因此所有方法属性都写在构造函数中,每次创建实例都
组合继承
function Parent(name) {
this.name = name
this.colors = ['red', 'blue', 'yellow']
}
Parent.prototype.sayName = function() {
console.log(this.name)
}
function Child(name, age) {
// 继承父类构造函数中的方法和属性并防止引用类型共享
// 使子类可以向父类传参
Parent.call(this, name)
this.age = age
}
// 继承父类原型上的方法
Child.prototype = new Parent()
Child.prototype.sayAge = function() {
console.log(this.age)
}
let child1 = new Child('xiaoye', 18)
child1.colors.push('green')
console.log(child1.colors) // ['red', 'blue', 'yellow', 'green']
child1.sayName() // xiaoye
child1.sayAge() // 18
let child2 = new Child('xiaoshi', 20)
console.log(child2.colors) // ['red', 'blue', 'yellow']
child2.sayName() // xiaoshi
child2.sayAge() // 20
优点
1.父原型上的方法可以被子类复用
2.父原型的引用属性不会被子类共享
3.实例化时子类可以向父类传递参数
组合继承结合了原型链继承与构造函数继承的优点,解决了彼此使用上的缺点,是项目中我们最常用的一种继承方式