面向对象编程oop之继承
将需求抽象成一个对象,这个对象我们称之为类
特点就是封装、继承和多态
关于继承
类式继承(将父类的实例化对象作为子类的实例化对象的原型)
把父类new 出来的实例赋值给子类的原型对象,也就是:
子类的prototype = 父类的实例(Child.prototype === new Parents()
)
当我们实例化一个父类的时候,新创建的对象复制了父类构造函数内的属性和方法,并且将原型_proto_指向了父类的原型对象,这样就可以访问父类的原型对象的属性和方法,同时也可以访问从父类构造函数中复制出来的属性和方法,然后将这个对象赋值给子类的原型,子类的原型也可以访问新建对象可以访问的父类的所有属性和方法,这就是类式继承
instanceof可以用来检测个某个对象是否是某个类的实例,或者说某个对象是否是后面类(对象)的实例
instanceof是通过判断对象的prototype链来确定这个对象是否是某个类的实例,而不关心对象与类的自身结构
缺点:
1.由于子类通过其原型prototype对父类实例化,继承父类,当父类的共有属性是引用类型的时候,就会在子类中被所有的实例共用,就会产生影响 2.由于子类实现的继承是靠其原型prototype对父类实例化实现的,因此在创建父类的时候,无法向父类传递参数,因而在实例化父类的时候,无法对父类的构造函数内的属性进行初始化
构造函数继承
function SubClass(id){
SuperClass.call(this,id) // 构造函数继承的精华
}
由于call可以改变函数的作用环境,因此在子类中对SuperClass调用这个方法就是将子类中的变量在父类中执行一遍,由于父类中是给this绑定属性的,因此子类自然就继承了父类的共有属性。
由于这个继承没有涉及到prototype,所以父类的原型方法不会被子类继承,要想被继承,即必须放在构造函数中
组合继承
简而言之就是让两种继承模式综合到一起
// 声明子类,在子类构造函数中执行父类构造函数
function SubClass(id){
SuperClass.call(this,id) // 构造函数继承的精华
}
// 在子类原型上实例化父类
SubClass.prototype = new SuperClass()
这样就融合了两种继承的优点,过滤掉缺点
原型式继承
类似类式继承
function inheritObject(o){
// 声明一个过度函数对象
function F(){}
// 过度对象的原型继承父对象(类似父类的实例)
F.prototype = o
return new F()
}
寄生式继承
其实就是原型式继承的子类的实例上面拓展新方法
function createBook(obj){
// 通过原型式继承创建新对象
var o = new inheritObject(obj)
// 拓展新对象
o.getName = function(){
console.log(name)
}
// 返回拓展后的对象
return o
}
寄生组合式继承
/**
* 寄生式继承 继承原型
* 传递参数 subClass 子类
* 传递参数 superClass 父类
*/
function inheritPrototype(subClass,superClass){
// 复制一份父类的原型副本保存到变量中
var p = inheritObject(superClass.prototype)
// 修正因为重写子类原型导致子类的constructor属性被修改
p.constructor = subClass
// 设置子类的原型
subClass.prototype = p
}
// 类似这样的
function SubClass(name,time){
SuperClass.call(this,name) // 构造函数继承的精华
this.time = time
}
// 在子类原型上实例化父类
inheritPrototype(subClass,SuperClass)
// 子类新增原型方法
subClass.prototype.getTime = function(){
console.log(this.time)
}
关于多继承和多态
多继承js的实现方式就是将多个对象的属性复制到源对象中,以实现对多个对象的属性继承
多态本质上是一个方法有多种调用方式,js一般的实现方式就是根据参数判断不同的调用方式
转载自:https://juejin.cn/post/6881878856983117832