js继承

296 阅读2分钟

随便聊聊js的继承,因为js本身是没有类的概念的,那么如何去实现继承?

这里举几种常见的继承方式:

1.构造函数继承

// Person在这里是超类型(父类、基类都行),即被继承的函数
function Person (name, age) {
    this.name = name
    this.age = age
}

// Student在这里是子类型(子类、派生类都行),即继承的函数
function Student (name, age, className) {
    Person.call(this, name, age)
    this.className = className
}

var stu = new Student('小红', 20, '软件九班')

console.log(stu.name)         // 小红
console.log(stu.age)          // 20
console.log(stu.className)    // 软件九班

这种方式的缺点:没有原型,不可复用

2.原型链继承

function Person () {
    this.name = '小红'
    this.age = 20
}

function Student () {
    this.className = '软件九班'
}

Student.prototype = new Person()

var stu = new Student()

console.log(stu.name)         // 小红
console.log(stu.age)          // 20
console.log(stu.className)    // 软件九班

这种方式的缺点:字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数

3.组合继承

function Person (age) {    this.name = '小红'    this.age = age}
Person.prototype.show = function () {    console.log(this.name, this.age)}function Student (age) {    Person.call(this, age)    this.className = '软件九班'}
Student.prototype = new Person()
var stu = new Student(21)
console.log(stu.name)         // 小红console.log(stu.age)          // 20console.log(stu.className)    // 软件九班stu.show()                    // 小红,21

这种方式:原型链实现对原型属性及方法的继承,构造函数实现了对实例属性的继承,但是Person会调用两次

4.寄生式组合继承,其实就是利用Object.create

function Person (name, age) {    this.name = name    this.age = age}
Person.prototype.show = function () {    console.log(this.name, this.age)}
function Student (name, age, className) {    Person.call(this, name, age)    this.className = className}
Student.prototype = Object.create(Person.prototype)
Student.prototype.show = function () {    Person.prototype.show.call(this)    console.log(this.className)}
var stu = new Student('小红', 20, '软件九班')stu.show()  // 小红 20 软件九班

解决Object.create兼容问题

function create (o) {    function F() {}    F.prototype = o    return new F()}

个人觉得,ES5之前的写法,这种方式最好

5.ES6的class

class Person {    constructor (name, age) {        this.name = name        this.age = age    }
    show () {        console.log(this.name, this.age)    }}
class Student extends Person {    constructor (name, age, className) {        super(name, age)        this.className = className    }
    show () {        super.show()        console.log(this.className)    }}
const stu = new Student('小红', 20, '软件九班')stu.show() // 小红 20 软件九班

ES6语法引入了类class的概念,这只是个语法糖,大部分功能ES5可以实现;这里用class会让写法更清晰,更像面向对象编程的语法。

好了,聊得差不多了。这次只是大概实现,下次再深入一点点。。。