1.原型链继承
继承就是子类继承父类的属性和方法
目的可以让子类的实例能够使用父类的属性和方法
类指的就是构造函数
2.原型链继承的核心
子类构造函数.prototype=父类的实例
子类构造函数.prototype.constructor=子类构造函数
3.特点
1.js继承是把父类的原型放到子类的原型链上,实例想要调用这些方法,其实是基于__proto__原型链的机制查找完成的。
2.子类可以重写父类上的属性和方法
3.父类中私有的或者公有的属性和方法,最后都会变成子类公有的属性和方法
// 父类构造函数
function A(X){
this.x=x
}
// 父类的公有的方法
A.prototype.getX=function(){
console.log(this.x)
}
//子类
function B(y){
this.y=y
}
//实现继承 把父类实例放到子类的原型上
B.prototype=new A('父类')
//原型链
B.prototype.constructor=B
B.prototype.getY=function(){
console.log(this.y)
}
//创建实例
let b=new B('子类')
console.log(b)
4.原型链继承分析图
2.call继承
call继承又称(借用构造函数继承)
在子类构造函数中把父类构造函数当作普通函数执行,并且通过call方法把父类构造函数中的this替换成子类的实例(this),这样相当于给子类实例上设置了私有的属性和方法。
特点
1.只能继承父类的私有的属性和方法(因为只是把父类构造当作普通函数执行了一次,跟父类的原型上的方法和属性没有任何关系)
2.父类的私有的属性和方法都会变成子类私有的属性和方法
// 父类
function A(x){
this.x=x
this.seyHello=function(){
console.log("hello world")
}
}
A.prototype,getX=function(){
console.log(this.x)
}
let a=new A(100)
//子类
function B(y,x){
this.y=y
A.call(this,x)
}
B.prototype.getY=function(){
console.log(this.y)
}
let b=new B(200,100)
console.log(b)
3.组合继承
结合原型链继承和借用构造函数继承组合起来实现的继承
特点
(call继承)中
1.子类实例可以使用父类私有的属性和方法
2.父类私有的属性和方法都会变成子类实例私有的属性和方法
(原型链继承)
3.子类实例可以通过原型链访问和使用父类公有的属性和方法
4.子类的原型链上会存在一份多余的父类的私有属性和方法
// 父类
function A(x){
this.x=x
this.seyHello=function(){
console.log("hello world")
}
}
A.prototype.getX=function(){
console.log(this.x)
}
// 子类
function B(y,x){
this.y=y
A.call(this,x)
}
B.prototype=new A()
B.prototype.constructor=B
B.prototype.getY=function(){
console.log(this.y)
}
let b =new B(200,100)
console.log(b)
4.寄生组合继承
结合原型链继承和call继承的方法,同时自己创建一个对象,并且让这个对象的原型指向父类构造函数的prototype.实现寄生组合继承。
特点
1.最完美的js继承解决方案
2.父类私有的属性和方法,成为子类实例私有的属性和方法
3.父类公有的属性和方法,成为子类实例公有的属性和方法
// 父类
function A(x){
this.x=x
this.seyHello=function(){
console.log("hello world")
}
}
A.prototype.getX=function(){
console.log(this.x)
}
//子类
function B(y,x){
this.y=y
A.call(this,x)
}
B.prototype=Object.create(A.prototype)
B.prototype.constructor=B
B.prototype.getY=function(){
console.log(this.y)
}
let b =new B(200,100)
console.log(b)
Object.create=function (arg){
function NewObj(){}
NewObj.prototype=arg
return new NewObj()
}
4.寄生组合继承分析图
5.Object.creat原理图
5. ES6中的Class类继承
ES6中新增了一个定义类的方法这样就不用我们手动的创建构造函数了
ES6 class继承通过extends来实现继承
class 子类 extends父类
在constructor中要使用super()
特点
1.父类私有的属性和方法会变成子类私有的属性和方法
2.父类公有属性和方法会变成子类公有的属性和方法
class B extends A{ //通过extends 实现原型链继承
consrtuctor(y){
super(100) // call继承(借用构造函数继承)
this.y=y
}
getY=function(){
console.log(this.y)
}
}
class B extends A{
// 如果不写consrtuctor,不会报错 继承会正常实现
// 如果不写consrtuctor,浏览器会自动的帮我们去创建一些代码
// consrtuctor(...arg){
//super(...arg)
//}
//consrtuctor(y){
//super(100)
//this.y=y
//}
getY=function(){
console.log(this.y)
}
}
let b =new B(200)
console.log(b)