面试宝典

2020-09-24(js的继承方式)

2020-09-24  本文已影响0人  宇宙区长李小无

前言

两天没写了,靠,怎么这么懒,废话不多说,来了来了。

继承

子类能够享有父类所拥有的属性和方法,在创建类似实例的时候非常有用。

原型链继承

不知道大家有没有搞清楚构造函数、实例对象、原型对象之间的关系,其实构造函数也是一个对象,js一切皆对象嘛,function也是通过new Function()来创建的,而且
Function.prototype.__proto__ === Object.prototype
我想说的是:每个实例对象都是通过__proto__指针来与其构造函数的原型对象进行关联的,访问属性时就是按照这条原型链。

第一种继承:简单的获取到父类的属性和方法

function Parent(name) {
    this.name = name || 'parentName';
}
Parent.prototype.sayName = function () {
    console.log(this.name);
}

function Son(age) {
    this.age = age;
}
Son.prototype = new Parent();
const son1 = new Son(18);

借用构造函数继承

子类在创建实例时可以传递参数给父类

function Parent(name) {
    this.name = name || 'parentName';
}
Parent.prototype.sayName = function () {
    console.log(this.name);
}

function Son(name, age) {
    Parent.call(this, name);
    this.age = age;
}
son1 = new Son("carter", 18);

原型加借用构造函数继承

前面两种方法的综合,借助原型链继承父类的原型属性和方法,借用构造函数(可以传参),继承父类的属性和方法,不存在共享属性的问题。

function Parent(name) {
    this.name = name || 'parentName';
}
Parent.prototype.sayName = function () {
    console.log(this.name);
}

function Son(name, age) {
    Parent.call(this, name);
    this.age = age;
}
Son.prototype = new Parent();
son1 = new Son("carter", 18);



缺点:

组合式继承

遇上述方法不同的是,在继承原型属性时,直接将子类原型对象指向父类的原型对象,这样就不需要调用两次构造函数了。

function Parent(name) {
    this.name = name || 'parentName';
}
Parent.prototype.sayName = function () {
    console.log(this.name);
}

function Son(name, age) {
    Parent.call(this, name);
    this.age = age;
}
Son.prototype = Parent.prototype;
son1 = new Son("carter", 18);

缺点:

寄生式组合继承

与组合式继承不同的是,在继承原型属性时,完全复制一个父类的原型对象指向子类原型。重写constructor。

function Parent(name) {
    this.name = name || 'parentName';
}
Parent.prototype.sayName = function () {
    console.log(this.name);
}

function Son(name, age) {
    Parent.call(this, name);
    this.age = age;
}
Son.prototype = Object.create(Parent.prototype);
Son.prototype.constructor = Son;
// Object.create原理:
// Object.create = function (protoObj) {
//  function F() {};
//  F.prototype = protoObj;
//  return new F();
// }
son1 = new Son("carter", 18);

ES6的class继承

class Parent {
    constructor(name) {
        this.name = name;
    }
    sayName() {
        console.log(this.name);
    }
}

class Son extends Parent {
    constructor(name, age) {
        super(name);
        this.age = age;
    }
}
son1 = new Son("carter", 18);

总结

ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

上一篇 下一篇

猜你喜欢

热点阅读