JS实现继承的几种方式

Js中的继承是指:通过某种方式,使子对象能够拥有父对象的属性和方法。

1.原型链继承1

添加属性至构造函数的prototype上,实例化的对象会继承构造函数prototype上的属性。

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

Person.prototype.say = function() {
    console.log("hello")
}
Person.prototype.run = function() {
    console.log("running")
}

let p1 = new Person();
p1.say(); //hello

缺点:添加多个属性时需多次Person.prototype。
存在代码冗余。

2.原型链继承2

新建对象,替换构造函数原有的prototype属性,避免代码冗余。

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

Person.prototype = {
    constructor: Person(),
    say:function(){
        console.log("hello")
    },
    run:function(){
        console.log("running")
    },
}

let p1 = new Person();
p1.say(); //hello

注意:需添加constructor属性,不破坏原有原型对象的结构。

3.拷贝继承

当想要使用某个对象的属性,但不能直接修改其属性的值时使用拷贝继承。
例:

let o1 = {name:'lisi',age:21};
let o2 = o1;
o2.age = 33;
console.log(o1.age) //33

直接对o2赋值为o1,o2获得的是o1的引用,所以对o2的修改也会对o1造成改变。

可使用es6的展开语法...进行浅拷贝。

let o1 = {name:'lisi',age:21};
let o2 = {...o1};
o2.age = 33;
console.log(o1.age) //21

4.原型式继承

场景:
1.新建一个继承于父对象的子对象。

let o1 = {name:'lisi',age:21};
let o2 = Object.creat(o1);
//o2.__proto__ === o1;

2.创建一个纯净的空对象。
即使我们赋值1个空的对象字面量,它的原型也会指向Object,并不纯洁。

通过 Object.creat(null) 可创建1个完全纯洁的空对象。

5.借用构造函数继承

当两个构造函数相似时,可以通过call/apply实现继承,避免代码冗余。

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

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

可以看到Animal和Person大部分属性相同,我们就可以通过apply/call来简化代码。

function Animal(name,age,gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
    // 当父类代码不适用于子类时不适用该方法
    // this.color = color;
    
}

function Person(name,age,gender,work,say){
    // 将Animal的this指向Person的实例
    Animal.apply(this,[name,age,gender])
    this.work = work;
    this.say = say;
}

可以形象理解成 马云.apply(我,[挣钱,演讲,...]) 便于记忆。
缺点:
父类(Animal)代码必须完全适用于子类(Person)。

评论

此博客中的热门博文

1. Angular 错误:ExpressionChangedAfterItHasBeenCheckedError