想要实现继承,就必须有一个父类,为了方便演示,本文将使用的父类统一定义
function Person (name, age) {
this.name = name;
this.age = age
}
// 给父类原型上添加 skin 属性
Person.prototype.skin = 'yellow'
复制代码
原型链继承
function People (name) {
this.name = name
}
People.prototype = new Person() // 主要操作: 将父级的实例对象作为子类的原型
let people = new People('zs')
console.log(people.skin) // yellow
console.log(people instanceof Person) // true
复制代码
特点:
- 只能继承父级原型上的属性和方法
- 所有子类的实例都会共享到父级原型上的属性和方法
构造函数继承
function People() {
Person.call(this, 'zs', 18) // 主要操作: 将父级函数在子类函数中进行复制
this.age = 19
}
let people = new People()
console.log(people.name) // zs
console.log(people.age) // 19
console.log(people.skin) // undefined
console.log(people instanceof Person) // false
复制代码
特点:
- 只继承了父类构造函数的属性,没有继承父类原型上的属性
- 可以向父类传参
组合继承(常用)
组合原型链继承和构造函数继承
function People () {
Person.call(this, 'lisi', 20) // 主要操作: 构造函数模式
}
People.prototype = new Person() // 主要操作: 原型链模式
let people = new People()
console.log(people.name) // lisi
console.log(people.age) // 20
console.log(people.skin) // yellow
console.log(people instanceof Person) // true
复制代码
特点:
- 可以传参,也可以复用,常用的一种继承
- 每个实例的属性都是私有的
- 子类的构造函数会替换原型上那个父类的构造函数
原型式继承
function People (obj) {
function Son () {}
Son.prototype = obj // 主要操作: 将子类的原型指向父类的实例对象
return new Son()
}
let f = new Person() // 实例化父类
let people = People(f)
console.log(people.skin) // yellow
console.log(people instanceof Person) // true
复制代码
特点:
- 跟原型链继承类似,只能继承到父类原型上的属性
- 所有的实例都会继承到父类原型上的方法
寄生式继承
function People (obj) {
function Son () {}
Son.prototype = obj // 主要操作: 将子类的原型指向父类的实例对象
return new Son()
}
function Merge(obj) {
let merge = People(obj) // 调用函数创建一个对象
merge.gender = '男' // 可以在这里添加属性
return merge
}
let people = Merge(new Person('zs', 20)) //继承父类构造函数的属性
console.log(people.name) // zs
console.log(people.age) // 20
console.log(people.gender) // 男
console.log(people.skin) // yellow
console.log(people instanceof Person) // true
复制代码
特点:
- 类似原型式继承,只不过是在外面套了个函数
- 可以继承到父类构造函数和原型上的属性
寄生组合式继承(常用)
function people (obj) {
function Son () {}
Son.prototype = obj
return new Son()
}
let f = people(Person.prototype) // f 实例继承了父类原型的属性
function Merge() {
Person.call(this, 'zs', '20') // 这里继承了父类构造函数的属性
}
Merge.prototype = f // 组合构造函数继承了父类原型的属性
f.constructor = Merge // 修复实例
let peo = new Merge()
console.log(peo.name) // zs
console.log(peo.age) // 20
console.log(peo.skin) // yellow
console.log(peo instanceof Person) // true
复制代码
特点:
- 可以向父类传参
- 子类实例可以继承到父类原型上的属性
- 可以复用
ES6中的继承
// 定义一个父级类
class Person {
constructor (uname, age, sex) {
this.uname = uname
this.age = age
this.sex = sex
}
sayHi() {
console.log('hello')
}
}
// 子类继承父类
class Chinese extends Person {
constructor (uname, age, sex, score) {
// 先用super调用父类的constructor
super(uname, age, sex)
this.score = score
}
sayHi() {
super.sayHi()
}
}
// 实例化子类
let person = new Chinese('张三', 22, '男', 99)
console.log(person.uname) // 张三
console.log(person.age) // 22
console.log(person.sex) // 男
console.log(person.score) // 99
person.sayHi() // hello
复制代码
如果子类有自己的 constructor
,必须通过super
才可以调用父类的成员
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END