一、继承的定义
继承是出现在两个构造函数之间的关系,当A构造函数的属性和方法被B构造函数的实例使用了,那么我们就说B继承自A构造函数A是B构造函数的父类或超类,B是A构造函数的子类。
// 构造函数 Person
function A() {
this.name = '小明'
this.age = 18
}
A.prototype.sayHi = function () {
console.log('hi')
}
// 实例化构造函数
let p1 = new A()
// 构造函数 Student
function B() {
this.class = '小号'
this.age = 18
}
let s1 = new B()
二、原型链继承
原型链继承就是通过改变原型链的方式来达到继承的效果
如:子类.protype = 父类的实例
原型链继承的缺点:
继承下来的属性并没有继承在自己身上,而是在__proto__里面,当访问的时候要去 __proto__里面找,要用的多个参数在多个位置传递,不利于代码的维护和阅读性。
function Person(name) {
this.name = name
}
Person.prototype.sayHi = function () {
console.log('hi')
}
// 实例化构造函数
let p = new Person('小红')
// console.log(p)
// 构造函数 Student
function Student() {
this.age = 18
}
Student.prototype = new Person('小明')
let s = new Student()
console.log(s.name)
console.log(s.sayHi)
三、构造函数继承
构造函数继承:
在子类的构造函数体内,借用构造函数执行一下, 并且强制让父类的构造函数的this指向子类的实例
构造函数继承的优点:
继承来的属性下载了自己的身上;
自己需要的两个属性在一个构造函数里传递;
构造函数继承的缺点:
只能继承父类的属性;
不能继承父类的原始性protype上的方法;
function Person(name, gender) {
console.log(this)
this.name = name
this.gender = gender
}
Person.prototype.sayHi = function () {
console.log('hi')
}
// let p = new Person('小明', '男')
// 构造函数 Student (子类)
function Student(age, name, gender) {
this.age = age
// 改变this指向
Person.call(this, name, gender)
}
let s = new Student(18, '小红', '女')
console.log(s)
console.log(s.sayHi)
四、组合继承
组合继承:
继承 =》两个构造函数之间的关系(就是把两哥函数组合在一起来实现需求);
子类的实例使用父类的属性和方法。
// 父类
function Person(name, age) {
this.name = name
this.age = age
}
Person.prototype.sayHi = function () {
console.log('hi')
}
// 子类
function Student(gender, name, age) {
this.gender = gender
// 构造函数继承
Person.call(this, name, age)
}
// 原型继承
Student.prototype = new Person()
Student.prototype.sayHello = function () {
console.log('hi123')
}
let s1 = new Student('女', '小红', 18)
console.log(s1)
console.log(s1.sayHello)
// console.log(s1.age)
// console.log(s1.name)
// 注意
// 如果子类的原型上也添加了方法,要在实现原型继承以后再添加
// 否则,添加的sayHello会被继承的父类上的原型方法覆盖,sayHello就没意义了
五、es6的继承方法class
// es6 书写类的语法 :class
// es6 的继承关键字:extends 、super
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
sayHi() {
console.log('hi')
}
}
class Student extends Person {
constructor(gender, name, age) {
// super关键字 就相当于 es5语法中 Person.call(this, name, age)
// super就代表父类的构造函数,且他会自动改变this指向
// super要写在子类构造函数的第一行
super(name, age)
this.gender = gender
}
}
let s1 = new Student('女', '小红', 18)
console.log(s1)