概念
面向对象中 :类的"继承 封装 和多态"
- 封装:把实现某个功能的代码进行封装处理,后期想实现这个功能 直接调用这个函数即可,低耦合,高内聚
- 多态:重载:方法名相同,参数类型或者个数不同,这样会认为是多个方法 重写:子类重写父类方法
- 继承:子类继承父类的方法 ,子类的实例既拥有子类赋予的私有/公有属性方法 也想拥有父类赋予的私有/公有属性方法
原型继承
和传统后台语言中的继承不一样(后台:子类继承父类,会把父类的方法copy一份给子类)并没有把父类的方法copy一份给子类,而是建立子类和父类之间的原型链指向,后期子类实例访问父类提供的属性方法 也是基于__proto__一层层查找的
问题:
父类想要赋予其实例的私有属性x此时变成了子类实例ch的公有属性
子类实例可以基于原型链,修改父类实例原型上的方法(这样会对父类的其他实例也产生影响)
ch.__proto__.__proto__sum=function(类似于重写)
栗子
function Parent() {
this.x = 100
}
Parent.prototype.getX = function () { }
function Child() {
this.y = 200
}
Child.prototype = new Parent
Child.prototype.getY = function () { }
let ch = new Child
console.dir(ch);
解析
call继承
把父类当做普通方法执行(原型啥的就没啥作用了),让方法中的this是子类实例,这样可以达到让父类中赋予其实例的私有属性,最后也变为子类的实例私有属性
function Child() {
Parent.call(this)//ch.x=100
this.y = 200
}
寄生组合式继承
把call继承和变形原型继承混合在一起就实现了寄生组合式继承(推荐)
Child.prototype = Object.create(Parent.prototype)
栗子
function Parent() {
this.x = 100
}
Parent.prototype.getX = function () { }
function Child() {
Parent.call(this)//ch.x=100
this.y = 200
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.getY = function () { }
let ch = new Child
console.dir(ch);
es6中类的继承
ES6中继承extends(非常类似于寄生组合式继承)
一但使用extends并且编写了constructor必须在constructor函数第一行写上super
从原理上类似于call继承 super==> Parent.call(this)
class Parent {
constructor() {
this.x = 100
}
getX() { }
}
class Child extends Parent {
constructor() {
//一但使用extends并且编写了constructor必须在constructor函数第一行写上super
//从原理上类似于call继承 super==> Parent.call(this)
super()
this.x = 100
}
getY() { }
}
let ch = new Child
console.dir(ch)
总结:
- 后台继承是通过父类的copy 但是前端没有copy只是通过原型链机制完成继承
- ,这样会出现子类实例可以基于原型链,修改父类实例原型上的方法(这样会对父类的其他实例也产生影响),
- 所有我们要是用call继承继承父类实例私有属性 object.creat 创建空对象原型指向 指向父类的原型寄生组合式继承 es6用extends r
- 应用场景: 1. eact类组件用到了继承 2.自己写插件的时候