简述ES6/ES5原型链与继承

ES6之前,JavaScript没有类的概念,继承基于原型链。每个对象都有一个指向另一个对象或内部的[[prototype]]属性。

prototype

prototype属性使你有能力向对象添加属性和方法。例如:

object.prototype.name = value;

原型链

每个人对象都有一个指向它原型(prototype)对象的内部链接。每个原型对象又有自己的原型,知道某个对象的原型为null为止,这条链则终止。

原型链继承

将父类的实例作为子类的原型。

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

Person.prototype.getName = function(){
    return this.name;
}

function Girl(){
    
}

// 继承Person  (原型链继承)
Girl.prototype = new Person();

// 创建girl1
var girl1 = new Girl();
console.log(girl1.getName()) //summer
构造函数继承

使用父类的构造函数来增强子类实例(复制父类的实例属性给子类)

...
function Girl(){
    Person(this);//实现继承
    // this.name = 'minya';
}

var girl2 = new Girl();
console.log(girl2.name); // summer

在ES5中,所有的构造函数的__proto__都指向Function.prototype。

在ES6中,构造函数的__proto__指向它的父类构造函数。

如:

object.__proto__ === object.[[prototype]];
// ES5
girl1.__proto___ === Girl.prototype;
// ES6
girl1.__proto__ === Girl

(….其他继承方式,待补充)

ES6继承

ES6提供了基础类Class。

例如:

class Person{
    constructor(name,age) {
        this.name = name;
        this.age = age;
    }
    sayHello() {
        console.log(`My name is ${this.name}, I'm ${this.age} years old.`)
    }
    toString() {
        return `My name is ${this.name}, I'm ${this.age} years old.`;
    }
}

class Girl extends Person {
    constructor(name,age,sex) {
        super(name,age);//继承父类的contructor
        this.sex = sex;
    }
    aboutSex() {
        console.log(`I'm a ${this.sex}.`)
    }
    toString() {
        return this.aboutSex() + super.toString();// 调用父类的toString()
    }
}

注意,子类必须在constructor中先使用super()调用父类

因为子类通过super获取父类this实现继承,否则后边的this.sex会因获取不到this而报错。

super关键字,有两种用法:

  • 作为函数调用(super(…args)),super代表父类的构造函数。
  • 作为对象调用(super.prop或super.method()),super代表父类。注,此时super可以引用父类实例的属性和方法,也可以引用父类的静态方法。
静态方法

类似于原型方法,但是不能由类实例调用。

class Person{
    ...
    
    static personExamples() {
        // 静态方法
        return `这是个静态方法,不能由类实例调用,可以用super调用`
    }
}

class Girl extends Person {
    ...
    
    showTime() {
        console.log(
        	Person.personExamples(),
            super.personExamples()
        );
    }
}

关于继承,还有很多需要补充的点,待完善。