zoukankan      html  css  js  c++  java
  • 继承方式

    参考文章:https://segmentfault.com/a/1190000016708006

    原型链继承

    子类的原型为父类的一个实例对象。

    function Person(name) {
        this.name = name
    }
    
    Person.prototype.setAge = function () { }
    
    function Student(score) {
        this.score = score
    }
    
    Student.prototype = new Person()    //子类的原型为父类的一个实例对象

    创建子类的时候,无法向父类传参

    借用构造函数继承

    在子类构造函数中通过call()调用父类型构造函数

    function Person(name) {
        this.name = name
    }
    
    Person.prototype.setAge = function () {
        console.log('age')
    }
    
    function Student(name, score) {
        Person.call(this, name) //使用call
        this.score = score
    }
    
    var s1 = new Student('xiaoming', '100')
    console.log(s1.setAge())//Uncaught TypeError: s1.setAge is not a function

    创建子类的时候可以向父类传参,但是不能继承父类原型属性和方法(如setAge)

    原型链+借用构造函数

    function Person(name) {
        this.name = name
        console.log('调用构造函数')
    }
    
    Person.prototype.setAge = function () {
        console.log('age')
    }
    
    function Student(name, score) {
        Person.call(this, name) //使用call,调用一次构造函数
        this.score = score
    }
    
    Student.prototype = new Person()    //调用一次构造函数
    Student.prototype.constructor = Student
    
    var s1 = new Student('xiaoming', '100')
    s1.setAge()    //age

    可以向父类传参,可以继承父类原型属性和方法。

    缺点:调用了两次父类构造函数。上面代码中,创建s1实例时,'调用构造函数'会打印两次

    组合继承优化

    将父类原型和子类原型指向同一个对象

    function Person(name) {
        this.name = name
        console.log('调用构造函数')
    }
    
    Person.prototype.setAge = function () {
        console.log('age')
    }
    
    function Student(name, score) {
        Person.call(this, name) //使用call,调用一次构造函数
        this.score = score
    }
    
    Student.prototype = Person.prototype    //不再调用构造函数,直接将两个原型指向同一个
    Student.prototype.constructor = Student
    
    var s1 = new Student('xiaoming', '100')
    s1.setAge()    //age

    优化了上个方法的父类构造函数调用两次的缺陷

    缺点:没办法辨别实例是子类还是父类创建的

    var s1 = new Student('xiaoming', '100')
    var p1 = new Person('xiaoming ')
    
    console.log(s1 instanceof Student)  //true
    console.log(s1 instanceof Person)   //true
    console.log(s1.constructor === Student) //true
    console.log(s1.constructor === Person) //false
    console.log(p1.constructor === Student)  //true (p1应该是Person实例化,这里结果混乱)
    console.log(p1.constructor === Person)  //false

    Object.create()

    var B = Object.create(A)以A对象为原型,生成B对象,B继承A所有属性和方法

    function Person(name) {
        this.name = name
    }
    
    Person.prototype.setAge = function () {
        console.log('age')
    }
    
    function Student(name, score) {
        Person.call(this, name) //使用call,调用一次构造函数
        this.score = score
    }
    
    Student.prototype = Object.create(Person.prototype)   //使用Object.create()来实现类式继承
    Student.prototype.constructor = Student
    
    var s1 = new Student('xiaoming', '100')

    class

    class Person {
        constructor(name) {
            this.name = name
        }
    
        setAge() {
            console.log('age')
        }
    }
    
    class Student extends Person {
        constructor(name, score) {
            super(name) //通过super调用父类的构造方法
            this.score = score
        }
    }
    
    let s1 = new Student('xiaoming', '100')
    s1.setAge()
  • 相关阅读:
    CSS属性选择器
    JS中For循环中嵌套setTimeout()方法的执行顺序
    document.getElementsByTagName()方法的返回值
    常见浏览器及其内核
    git与svn的区别
    JS解析URL参数为对象
    CSS中的伪类和为伪元素
    CSS中:first-child伪类
    CSS链接使用伪类的顺序
    CSS行内框(内联元素)
  • 原文地址:https://www.cnblogs.com/lianglanlan/p/14457865.html
Copyright © 2011-2022 走看看