认识继承
实例:
function Person(name) {
this.name = name
}
Person.prototype.init = function () {
console.log('我是 Persion 原型上的方法')
}
function Stu (age) {
this.age = age
}
Stu.prototype.sayHi = function(){
console.log('你好')
}
const s1 = new Stu(18)
console.log(s1)
在上述实例中,如果 s1 对象内部 具有一个属性为 name, 并且 s1 还可以使用 init 方法, name 我们就可以说 Stu 这个构造函数 继承自 Person 构造函数
Stu 是 Person 的子类 Person 是 Stu 的父类
原型继承
原型继承: 利用 自定义原型 的方法实现继承关系
核心: 将子类的原型修改为父类的实例化对象
优点: 可以使用父类的属性和方法, 实现了继承
缺点:
1. 原本原型上的方法不能再使用了 (因为原型对象被改变成了父类的实例化对象)
2.继承到的属性并不在自己身上, 而是在 原型对象上(不过不影响使用)
实例:
function Person(name) {
this.name = name
}
Person.prototype.init = function () {
console.log('我是 Persion 原型上的方法')
}
function Stu (age) {
this.age = age
}
Stu.prorotype = new Person('彭于晏')
Stu.prototype.sayHi = function(){
console.log('你好')
}
const s1 = new Stu(18)
console.log(s1)
借用构造函数继承
核心: 把父类构造函数当做普通函数调用, 并利用 call 修改这个函数内部的 this 指向(如果不修改的话, 函数的 this 指向了其他的对象)
优点: 把父类的属性全都继承在了自己的身上
缺点: 1. 只能继承父类的属性, 不能继承父类的方法
2. 每次调用 Stu 的时候, Stu内部还会自动调用一次 Person 函数
例:
function Fn (name){
this.name = name
}
Fn.prototype.init = function (){
console.log('我是添加在 Fn 原型上的方法')
}
function Fn2 (age, name){
this.age = age,
Fn.call(this, name)
}
Fn2.prototype.sayHi = function(){
console.log('你好')
}
const f1 = new Fn2(41,'彭于晏')
console.log(f1)
组合继承
核心: 把原型继承与借用构造函数继承结合起来使用
优点: 实例化对象上具有继承到的属性, 并且能够继承到父类原型上的方法
缺点: 实例化对象上与原型对象上, 都有父类的属性(多了一套属性,但是不影响使用)
例:
function Fn (name){
this.name = name
}
Fn.prototype.init = function(){
console.log('我是添加在 Fn 原型上的方法')
}
fucntion Fn2 (age, name) {
this.age = age
Fn.call(this,name)
}
Fn2.prototype = new Fn()
Fn2.prototype.sayHi = fucntion (){
console.log('我是添加在 Fn2 原型上的方法')
}
const f1 = new Fn2(23,'秦霄贤')
console.log('Fn2的实例化对象:', f1)
f1.init()
拷贝继承
通过for...in遍历对象,以及可以遍历对象 的构造函数的 原型上的 方法来实现拷贝继承
例:
fonction Fn1 (age) {
this.age = age
}
Fn1.prototype.init = ()=>{
console.log('我是添加在 Fn1 原型上的方法')
}
function Fn2 (name,age){
this.name = name
const f1 = new Fn1('秦霄贤')
for(let key in f1){
Fn2.prototype[key] = f1[key]
}
}
Fn2.prototype.sayHi = () =>{
console.log('你好')
}
const f2 = new Fn2('秦霄贤',24)
consol.log('Fn2的实例化对象:', f2)
ES6 类 的继承
语法要求:
1.书写 子类 的语法: class 子类类名 extends 父类类名{...}
2.书写 constructor 的时候: 内容需要写 super('父类需要的参数')
注意:
1.extends 和 super 必须同时出现才能完成继承
2.super 必须出现在 constructor 的第一行
扩展:
ES6 类也能继承 ES5 的构造函数
验证方法:将 父类 更改为 ES5 的构造函数写法即可
例:
class Fn {
constructor (name){
this.name = name
}
inir(){
console.log('我是添加在 Fn 原型上的方法')
}
}
function Fn(name){
this.name = name
}
Fn.prototype.init = () => {
console.log('我是添加在 Fn 原型上的方法')
}
class Fn2 extends Fn{
constructor(age, name){
super(name)
this.age = age
}
sayHi(){
console.log('我是添加在 Fn2 原型上的函数')
}
}
const f1 = new Fn2(24,'秦霄贤')
console.log(f1)
console.log(f1.name)