es5的继承和es6的class继承

387 阅读2分钟
1. __proto__:
     对象特有
     指向上层级(创建自己的那个构造函数)的原型(prototype)
     对象从prototype继承属性和方法

2.prototype:
	函数特有
	用于存储要共享的属性和方法

3.constructor:
	函数特有,定义在prototype里面
	通过new创建实例,该实例继承了prototype的属性和方法

4.Object:是对象,也是构造函数
	作为函数:
	object.prototype是原型链的顶端,object.prototype._proto_=null
	作为对象:
	object.__proto__=function.prototype

原型链继承:

它的优点是可以继承父类的方法, 缺点:不能传参,

 function Person(name = '没有名字', age = 0) {
         this.name = name;
         this.age = age;
     }
     //添加到原型上面,方便复用,无论多少实例对象,都会在原型prototype上, prototype可理解为一个公共模板
     Person.prototype.getName = function () {
         return this.name
     }
             //new实例化对象
             // let p1 = new Person('wzl', 20)
             // let p2 = new Person('wz琳123', 20)
             console.log(p1.getName())
             console.log(p2.getName())
             console.log(p1.getName===p2.getName)  //true
     //创建子类Child
     function Child() {
         this.address = '山西'
     }
     //原型链继承
     Child.prototype = new Person('wzl',20)
     let p3 = new Child()
     console.log(p3.name)
     console.log(p3.age)
     console.log(p3.address)
     console.log(p3.getName())

构造函数继承

借助call、apply 通过在子类中对父类传递参数

优点:传参方便

缺点:不可以继承父类的方法

  function Preson(name,age){
            this.name=name;
            this.age=age;
    }
    function Child(name,age){
        Preson.call(this,name,age)
        this.address='山西'
    }
    let p2 =new Child('加油',21)
    console.log(p2)

组合式继承

既可以调用自己的方法,也可以使用父类原型上的方法

function Preson(name,age,address='北京'){
            this.name=name;
            this.age=age;
    }
    Preson.prototype.GetName=function(){
        return this.name
    }
    function Child(name,age,address){
        Preson.call(this,name,age)
        this.address=address
    }
    Child.prototype=new Preson()
    //子类添加一个方法
    Child.prototype.getAddress=function(){
        return `用户为${this.name}地址为${this.address}`
    }
    let p2 =new Child('加油啊',21,'太原')
    console.log(p2)
    // 查看自己的方法
    console.log(p2.getAddress())
    //查看父类的原型上的方法
    console.log(p2.GetName())

es6 class继承

在当前实例化属性中查找有没有,没有则通过__proto__查找父类的原型

父类原型有则执行,没有则在通过__proto__再往上查找,查父类的父类的原型

以此类推...走到查找到null,即为原型链的最顶端

//定义父类
     class Preson{
         //通过constructor来定义实例化的属性  相当于es5的构造函数
         constructor(name='无名',age=0){
             this.name=name
             this.age=age
         }
         //相当于es5中的原型prototype上定义的方法
         getName(){
             return this.name
         }
     }

    //  let p1 =new Preson('wzl琳',20)
    //  let p2 =new Preson('wzl琳123',23)
    //  console.log(p1.name)
    //  console.log(p1.age)
    //  console.log(p1.getName===p2.getName)   //true
        //定义子类   继承父类的Preson
        class Child extends Preson{
        constructor(name,age){
            //es6 继承必须要调用super(super指向父类),才能在子类中使用this
            super(name,age)
            this.name=name
        }
    }
    let p1 =new Child('wzlES6继承',20)
    console.log(p1)
    console.log(p1.getName())

el6 引入:import 抛出:export 当然还有服务端常用的:引入require 抛出module.exports

还有呢就是如果想在本地html页面使用模块化的话,将script标签上添加type="module"即可