JS 的继承

一.原型链继承

特点:子类型的原型是父类型的一个实例对象 父类新增原型方法或原型属性子类都会访问到 简单易于实现

子类的实例通过 _proto_ 访问到父亲的实例 这样就可以访问父类的私有方法 然后通过 _proto_ 指向父类的 prototype 获得父亲原型上的方法 这样做到将父类的私有 公有方法和属性都当做子类的公有属性和方法 

缺点:无法实现多继承

     来自原型对象的所有属性被所有实例共享

     创建子类实例时 无法向父类构造函传参

     想给子类新增属性和方法要在 son.prototype = new fa() 之后执行 不能放到构造器

二.构造函数继承

特点:在子类构造函数中用 call() 调用父类构造函数 只能继承父类的属性和方法 不能继承父类原型的属性和方法

     解决了原型链继承者子类实例共享父类引用属性的问题 创建子实例时可以向父类传递参数 

     可以多继承 call 多个夫类对象

缺点:实例并不是父类的实例 只是子类的实例

     只能继承父类的实例属性和方法 不能继承原型属性和方法

     不能函数复用 每个子类都有父类实例函数的副本 影响性能

三.原型链 + 构造函数

通过调用父类构造 继承父类的属性并保留传参的优点 通过将父类实例作为子类原型实现函数复用

优点:可以继承实例属性 方法 也可以继承原型属性方法

     不存在引用属性共享问题

     可传参

   函数可复用

缺点:调用两次父类构造函数生成两份实例

function Person(name, age) {
            this.name = name,
            this.age = age,
            this.setAge = function () { }
        }
        Person.prototype.setAge = function () {
            console.log("111")
        }
        function Student(name, age, price) {
            Person.call(this,name,age)
            this.price = price
            this.setScore = function () { }
        }
        Student.prototype = new Person()
        Student.prototype.constructor = Student
        Student.prototype.sayHello = function () { }
        var s1 = new Student('Tom', 20, 15000)
        var s2 = new Student('Jack', 22, 14000)
View Code

四.组合继承优化1

通过父类原型和子类原型指向同一对象 子类可以继承到父亲的公有方法当作自己的公有方法 不会初始化两次实例方法 避免组合继承的缺点

优点:不会初始化两次实例方法 避免组合继承的缺点

缺点:没办法辨别实例是子类还是父类创造的 子类和父类构造函数指向是同一个

五.组合继承优化2

借助原型可以基于已有的对象来创建对象 var B = Object.create(A) 以 A 对象为原型 生成 B 对象 B 继承 A 所有属性和方法

核心:B.prototype = Object.create(A.prototype)

   B.prototype.constructor = B

六.ES6 中 class 的继承

class extends 继承 

优点:操作方便

缺点:不是所有浏览器都支持 class 关键字

posted @ 2019-12-25 11:08  丧心病狂工科女  阅读(138)  评论(0编辑  收藏  举报