js继承(ES5,ES6)

初始化

function Person(name) {
        this.name = name
        this.type = ["css", "js", "html"]
        this.sum = function () {
            alert(this.name)
        }
    }
 Person.prototype.age = 10

一 原型链继承(ES5)

    function Per() {
        this.name = 'ker'
    }
    Per.prototype = new Person()
    var Per1 = new Per()
    var Per2 = new Per()
    Per1.type.push("vue")
    Per1.sum()  // ker
    console.log(Per1.age)   //10
    console.log(Per2.type)  //"css","js","html","vue"
    //instanceof 判断元素是否是另一个元素原型链上
    //Per1继承了Person的属性,返回为true
    console.log(Per1 instanceof Person)   //true

优点:简单明了

缺点:

1、新实例无法向父类构造函数传参

2、继承单一

3、 所有新实例都会共享父类实例属性(一个实例修改了原型属性,另一的原型属性也会随之更改)

二 借用构造函数继承(ES5)

    function Con() {
        Person.call(this, 'nima')

    }
    var Con1 = new Con()
    var Con2 = new Con()
    Con1.type.push("haha")
    console.log(Con1.age)    // underfined  没有继承父类原型的属性,只继承父类构造函数的属性
    console.log(Con1.name)   //nima
    console.log(Con1.type)  // 'css', 'js', 'html', 'haha'
    console.log(Con2.type)  // 'css', 'js', 'html'

优点:

1、解决了子类实例共享父类引用属性的问题

2、创建子类实例时,可以向父类构造函数传参

缺点:

1、没有继承父类原型的属性,只继承父类构造函数的属性

2、无法实现构造函数的复用

3、每个新实例都有父类构造函数的副本(臃肿)

三 组合继承(ES5)

    function SubType(name) {
        Person.call(this, name)   //构造函数继承
    }
    SubType.prototype = new Person()   //原型链继承
    var Sub = new SubType('铃铛')
    console.log(Sub.name)   //铃铛
    console.log(Sub.age)   // 10

优点:

 1、可以继承父类原型上的属性,可以传参可以复用

 2、 每一个构造函数属性都是私有的

缺点:

用了两次父类构造函数(耗内存),子类的构造函数会代替原型上的那个父类构造函数

四 原型式继承(ES5)

    //先封装一个函数容器,用于输出对象和承载继承的原型
    function Conent(obj) {
        var f = function () { }
        f.prototype = obj   //继承了传入的参数
        return new f()      //返回函数对象
    }
    var sup = new Person('naonao')  // 拿到父类的实例
    var sup1 = Conent(sup)
    console.log(sup1.name)      //naonao   继承父类函数的属性

重点: 用一个函数包装一个对象然后返回这个函数的调用,这个函数就变成了可是随意增添属性的实例或对象。object.create()就是这个原理

缺点:

1、所有的实例都会继承原型的属性

2、无法实现复用(新实例属性都是后面添加的)

五 寄生式继承(ES5)

    function Conent(obj) {
        var f = function () { }
        f.prototype = obj   //继承了传入的参数
        return new f()     //返回函数对象
    }
    var sup = new Person()  // 拿到父类的实例
    //以上是原型式继承,给原型式继承再套一个壳子传递参数
    function subObject(obj) {
        var sub = Conent(obj)
        sub.name = 'yvan'
        return sub
    }
    var sup2 = subObject(sup)   //这个函数声明之后就成了可增添属性的对象
    console.log(sup2.age)       //10
    console.log(typeof subObject) //function
    console.log(typeof sup2)  //Object

重点 :就是给原型式继承再套一个壳子

优点:

没有创建自定义类型,只是套了一个壳子返回对象。所以就顺理成章就创建了新对象

缺点:

没有用到原型无法复用

六:寄生组合式继承(ES5)

    function Conent(obj) {     //寄生
        function F() { }
        F.prototype = obj
        return new F()
    }
    var con = Conent(Person.prototype)
    //con实例(F实例)继承了父类函数的原型
    //更像原型链继承只不过继承了原型属性
    function SUb() {
        Person.call(this)    //这个继承了父类构造函数的属性
    }  //解决了组合式两次调用构造函数属性的缺点
    //重点
    SUb.prototype = con   //继承了con实例
    con.constructor = SUb     // 修改实例
    var sub1 = new SUb()
    console.log(sub1.age)     // 10

  特点 :修复了组合继承的问题

ES5继承总结:

继承这些知识点与其说是对象的继承,更像是函数的功能用法,如何用函数做到复用,组合,这些和使用继承的思考是一样的。上述几个继承的方法都可以手动修复他们的缺点,但就是多了这个手动修复就变成了另一种继承模式。

ES6的继承

   class Parent {
      constructor (name,age){
        this.name = name 
        this.age = age
      };
      tack(){
        console.log( '姓名:' + this.name)
        console.log( '年龄:' + this.age)
      }

   }
   class Son extends Parent{
       constructor (name , age ,sex){
            super(name,age);             //super必须在子类的this之前调用
            this.sex = sex;
       }
       disp(){
        console.log('性别:' + this.sex)
       }
       zonghe(){
        console.log(  this.name + '年龄:' + this.age +'性别:' + this.sex)
       }
   }
   var c1 = new Son('闹闹',1,'男')
   c1.tack()    //  姓名:闹闹     年龄:1
   c1.disp()   //  性别:男
   c1.zonghe()  //  闹闹年龄:1性别:男

重点:父类不能调用子类的方法和属性,也就是说子类的变化不会影响到父类

es6继承与与es5继承的区别:

1、es5的构造函数是普通函数,可以使用关键词new也可以直接用。es6的class不能当做浦东函数用必须要用new关键词。

2、es5的原型方法和静态方法可以枚举,class默认不可枚举,要想获取不可枚举属性可以使用Object.getOwnPropertyNames方法。

3、es5的继承,实质是先创造子类的实例对象this,再执行父类的构造函数向其添加实例方法和属性(也可不执行),而es6的继承机制是先创造父类的实例对象this,再用子类的构造函数修改this。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值