欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javascript继承的实现方法

程序员文章站 2024-03-18 21:25:10
...

1、原型链继承

核心:子类的原型指向父类的一个实例

function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.sayHi = function(){
    console.log('Hi!');
}

function Student(sex){
    this.sex = sex
}

Student.prototype = new Person()

var s1 = new Student(10)
var s2 = new Student(20)
console.log(s1)
console.log(s2);

注意:如果子类要设置自己的方法,需要在设置原型语句之后写
缺点:
1、所有子类共享同一个父类原型,如果是引用类型的属性,会同时修改
2、无法实现多继承
3、无法向父类传参
4、为子类增加方法需要在设置原型之后,不能放到构造器中

2、构造函数继承

核心:在子类构造函数中通过call调用父类构造函数

function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.sayHello = function(){
    console.log('Hello!');
}

function Student(sex, name, age){
    Person.call(this, name, age)
    this.sex = sex
}

var p1 = new Student(1,2,3)
console.log(p1);

缺点:
1、无法获取父类原型上的方法
2、实例只是子类的实例
3、每个实例都有父类函数的副本,影响性能

3、组合继承

function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.sayHello = function(){
    console.log('Hello!');
}

function Student(sex, name, age){
    Person.call(this, sex, name, age)
    this.sex = sex
}

Student.prototype = new Person()
// 需要修改构造函数指向
Student.prototype.constructor = Student

var p1 = new Student(4,5,6)
console.log(p1);

注意:需要修改子类构造函数指向
缺点:
1、调用了两次父类的构造函数,生成了两份实例

4、组合继承优化1

function Person(name, age){
    this.name = name;
    this.age = age;
}

Person.prototype.sayHello = function(){
    console.log('Hello!');
}

function Student(sex, name, age){
    Person.call(this, sex, name, age)
    this.sex = sex
}

// 子类与父类的原型指向同一个对象
Student.prototype = Person.prototype

var p1 = new Student(4,5,6)
console.log(p1);

缺点:不确定具体是哪个构造函数的实例

5、组合继承优化2

function Person(name, age){
   this.name = name;
    this.age = age;
}

Person.prototype.sayHello = function(){
    console.log('Hello!');
}

function Student(sex, name, age){
    Person.call(this, sex, name, age)
    this.sex = sex
}

// 以Person对象为原型生成Student对象
Student.prototype = Object.create(Person.prototype)
// 需要修改构造函数指向
Student.prototype.constructor = Student

var p1 = new Student(4,5,6)
console.log(p1);

目前来说这种方式是比较好的,没有明显缺陷

6、class继承

class Person{
   constructor(name, age){
        this.name = name
        this.age = age
    }

    showName(){
        console.log(`父类名字:${this.name}`)
    }
}

class Student extends Person{
    constructor(name, age, sex){
        super(name, age) // 这里调用父类的属性
        this.sex = sex
    }
}

let s1 = new Student('sum', 22, '男')
console.log(s1)
s1.showName()

ES6语法,有些浏览器不支持