面试-从es5最常用的继承到es6的继承

78 阅读3分钟

从刚开发入前端这行就一直在看网上的各种文章,好久每每在面试的时候都会看到继承的题,每次都感觉是明白了,但都是似懂非懂的,工作多年后再回过头来看的时候还是有不同的收获,比之前更加的清晰

给自己记录一下,好记性不如烂笔头

1 原型继承

总结一下特点

  • 1.不像其它语言中的继承一样(其它语言的继承一般是拷贝继承,也就是子类继承父类,会把父类中的属性和方法拷贝一份到子类中,供子类的实例调取使用),它是把父类的原型放到子害实例的原型链上,实例想调取这些方法,是基于__proto__原型链查找机制完成的
  • 2.子类可以重写父类上的方法(这样会导致父类其它的实例也受到影响)
  • 3.父类中私有或者公有的属性方法,最后都会变为子类中公有的属性和方法

代码实例

function Parent(x){
    this.x=x
}
Parent.prototype.getX=function(){
    console.log(this.x)
}
function Child(y){
    this.y=y
}
Child.prototype=new Parent(200)   这句是重点
Child.prototype.constructor=Child 
Child.prototype.getY=function(){
    console.log(this.y)
}
let child=new Child(100)
child.y
child.getY()
child.getX()

image.png

2 使用call来继承属性特点

  1. 在child方法中把parent当做普通函数执行,让parent中的this指向child的实例,相当于给child的实例设置了很多私有的属性或者方法
  2. 只能继承父类私有的属性和方法(因为是把parent当做普通函数执行,和其原型上的属性和方法没有关系)
  3. 父类私有的变为子类私有的

但是缺少父类公有的变成子类公有的

functioin Parent(x){
    this.x=x
}
Parent.prototype.getX=function(){
    console.log(this.x)
}
function Child(y){
    Parent.call(this,200) //call继承的使用改变this,这里的this是B的实例child,相当于 this.x=x
    this.y=y
}
Child.prototype.getU=function(){
    console.log(this.y)
}
let child=new Child(100)
child.y
child.x

3 寄生组合继承

call继承+类似于原型继承 特点-- 父类私有和公有的分别是子类实例的私有和公有属性方法

延续第call的写法

functioin Parent(x){
    this.x=x
}
Parent.prototype.getX=function(){
    console.log(this.x)
}
function Child(y){
    Parent.call(this,200)
    this.y=y
}
Child.prototype=Object.create(A.prototype) 等同于在中间搭了一个桥梁来把父类原型链上的公有方法变成子类的公有方法
Child.prototype.constructor=Child 
Child.prototype.getU=function(){
    console.log(this.y)
}
let child=new Child(100)
child.y
child.x

如何创建一个对象,让这个对象的原型链指向某个东西?

第一想到的是这种写法,但是一般没有这样写的,而且ie也是不能使用__proto__
Object.create=function(){  
    let oo={}
    oo.__proto__=obj
    return oo;
}
改成这种写法一样可以实现
Object.create=function(obj){
    function Fn(){}
    Fn.prototype=obj
    return new Fn()
}

image.png

4 es6 创建继承class 现项目中都使用这种方式

es6 中基于CLASS创造出来的类不能当做普通函数执行 重点使用extends child extends parent

class Parent{
    constructor(x){
        this.x=x
    }
    getX(){
        console.log(this.x)
    }
}
class Child extends Parent{
    constructor(){
        super(200)
        this.y=y
    }
    getY(){ //动态方法类的实例 this指实例
        console.log(this.y)
    }
    static getZ(){  //注静态方法只能给类自己调用,this指类本身
        console.log(this.y)
    }
}

如写的有问题欢迎大佬指点