class的继承 —— ECMAScript 6入门读书笔记

extends

使用extends关键字实现继承

class A {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}

class B extends A {
    constructor(x, y, z) {
        super(x, y);
        this.z = z;
    }
}
  1. 子类必须在constructor中调用supper,在ES5中,是先创建子类的实例对象this,然后再将父类的方法添加到this上面.ES6是先将父类对象的属性和方法,加到this上面(所以必须要先调用supper方法),然后在用子类的构造函数修改this

  2. 在子类中,只有在supper调用之后才能够使用this关键字,在supper调用之前输出(console.log(this))也不行,因为使用了this

Object.getPrototypeOf()

Object.getPrototypeOf()可一获得该类的直接父类

class A {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
}

class B extends A {
    constructor(x, y, z) {
        super(x, y);
        this.z = z;
    }
}

class C extends B {

}
console.log(Object.getPrototypeOf(B));
console.log(Object.getPrototypeOf(B) === A);
console.log(Object.getPrototypeOf(C));

super关键字

作为函数调用

作为函数调用的时候,代表父类的构造函数,但是返回的是子类的实例,即super内部的this指的是B的实例,因此super()相当于A.prototype.constructor.call(this)

class A {
    constructor(x, y) {
        console.log(new.target);
        this.x = x;
        this.y = y;
    }
}

class B extends A {
    constructor(x, y, z) {
        super(x, y);
        this.z = z;
    }
}

let a = new A(1, 2);
let b = new B(3, 4, 5);

作为对象使用

普通方法

在普通方法中,super指向父类的原型对象,即相当于A.prototype

在普通方法中,super指向父类的原型对象,所以父类实例上的方法和属性无法通过super进行使用

class A {
    constructor() {
        this.x = 1;
    }

}

A.prototype.y = 2;

class B extends A {
    constructor() {
        super();
    }

    getX() {
        //x是A的实例对象上的属性,无法获取到
        return super.x;
    }

    getY() {
        //y是A的原型对象上的属性,可以获取到
        return super.y;
    }
}
let b = new B();
console.log(b); //B { x: 1 }
console.log(b.getX()); //undefined
console.log(b.getY()); //2

比较有趣的是,虽然父类的实例对象上的方法和属性无法通过super获取到,但是可以通过super设置父类实例对象上的方法和属性,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例

class A {
    constructor() {
        this.x = 1;
    }
}

class B extends A {
    constructor() {
        super();
        console.log(this.x); //1
        super.x = 4;
        console.log(super.x); //undefined
        console.log(this.x); //4
    }
}
let b = new B();

使用super进行读时,super等同于A.prototype,并且内部的this指向当前子类实例,赋值时super等同于this

静态方法

在静态方法中使用super的时候,super相当于父类(A),而不是父类的显示原型属性(A.prototype),super调用父类的方法时,方法内部的this指向当前的子类,而不是子类的实例

class A {
    constructor() {
        this.x = 1;
    }

    static getX() {
        console.log(this.x);
        return this.x;
    }
}

class B extends A{
    constructor() {
        super();
        this.x = 2;
    }

    static print() {
        super.getX();
    }
}
B.x = 3;

B.print(); //3

使用super进行读取时,super等同于A,并且内部的this指向当前子类(不是子类实例),赋值时等同与this

class A {
    constructor() {
        this.x = 1;
    }

    static getX() {
        console.log(this.x);
        return this.x;
    }
}

class B extends A{
    constructor() {
        super();
        this.x = 2;
    }

    static print() {
        super.getX();
    }

    static setY() {
        super.y = 4;
        console.log(B.y); //4
        this.y = 666;
        console.log(B.y); //666
        console.log(super.y); //undefined
    }
}
B.x = 3;

B.print(); //3
B.setY();

你可能感兴趣的:(JavaScript,读书笔记,读书笔记,js,es6)