yizihan / blog

Record
1 stars 0 forks source link

ES6 - Class #16

Open yizihan opened 6 years ago

yizihan commented 6 years ago

Class

ES6引入了Class(类)这个概念,作为对象的模板。通过关键字class可以定义类。

class Point {
    // 构造方法,定义类的自身属性,this指向实例
    constructor(x, y) { 
        this.x = x;
        this.y = y;
    }
    // 类的方法 prototype(原型对象)的属性
    toString() {
        return '(' + this.x + ', ' + this.y + ')';
    }
}
typeof Point;   // function 所以类的数据类型还是函数
Point.prototype.constructor === Point;  // true 类本身指向构造函数

var point = new Point(100, 200)   // 通过new创建实例

类内部的所有方法是不可枚举的

Object.keys(Point.prototype);   // [] 空数组 不可枚举
Object.getOwnPropertyNames(Point.prototype);    // ['constructor', 'toString']

constructor 类的默认方法,通过new命令生成对象实例时,自动调用该方法,返回实例对象(this)。

自身属性与原型属性

point.hasOwnProperty('x');          // true  自身属性
point.hasOwnProperty('toString');   // false 原型属性

不存在变量提升

new Foo();      // ReferenceError
class Foo {}    

类的静态方法 静态方法中的this指向类

class Foo {
    // static 声明静态方法
    static classMethod () {
        // 静态方法中的this指向类
        console.log(this);
        return 'hello'
    }
}
var foo = new Foo();
class Bar extends Foo {};
Foo.classMethod();  // hello
Bar.classMethod();  // hello    类的静态方法可以被子类继承
foo.classMethod();  // is not a function

不能实例化只能被继承的类 new.target 指向new命令作用于的那个构造函数。 Class内部调用new.target,返回当前Class。

class Shape {
    constructor() {
        if(new.target === Shape) {
            return new Error('此类不能实例化');
        }
    }
}
class Rectangle extends Shape {
    constructor(length, width) {
        super();
        // ...
    }
}
var x = new Shape();    // 报错
var y = new Rectangle(3, 4);// 正常运行 

类继承

Class可以通过extends关键字实现继承。

class ColorPoint extends Point {
    constructor(x, y, color) {
        // 调用父类的constructor(x, y),继承父类的this和自身属性
        // !!!只有调用了super之后,才可以使用this关键字,否则会报错
        // 因为子类实例的构建时基于对父类实例加工,只有super方法才能返回父类实例
        super(x, y);  
        // 子类的自身属性
        this.color = color; 
    }
    toString() {
        // 调用父类的toString()
        return this.color + ' ' + super.toString();
    }
}

类的prototype属性和proto属性

class A {}
class B {}
B.__proto__ === A;      // true
B.prototype.__proto__ === A.prototype;  // true

参考:ES6入门