继承方式

参考文章: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()
原文地址:https://www.cnblogs.com/lianglanlan/p/14457865.html