【ES6】class基础(整理篇)

2,769 阅读2分钟

前言

上一篇整理了es6解构语法相关的一块知识(【ES6系列】解构赋值(整理篇))。这一篇,要整理的是class相关的知识。

什么是class

class就是类,和ES5中的构造函数十分相似,绝大部分功能都是一致的,但是class的写法,能让对象原型的功能更加清晰,更加符合面向对象语言的特点。

class的写法

  • 构造函数的写法
function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype.sayPoint = function() {
    console.log(`x: ${this.x}, y: ${this.y}`);
}
  • class的写法
class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    sayPoint() {
        console.log(`x: ${this.x}, y: ${this.y}`);
    }
}
  • class写法的注意点

1、constructor就是原来构造函数的写法。 2、定义类的方法的时候,并不需要加逗号,也不需要加function

  • 两者的区别

class的内部所有定义的方法,都是不可枚举的。而原型上面定义的方法都是可以枚举的。

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    sayPoint() {
        console.log(`x: ${this.x}, y: ${this.y}`);
    }
}
Object.keys(Point.prototype);  //[]
function Point(x, y) {
    this.x = x;
    this.y = y;
}

Point.prototype.sayPoint = function() {
    console.log(`x: ${this.x}, y: ${this.y}`);
}
Object.keys(Point.prototype);  //['sayPoint']

constructor方法

constructor是类的默认方法,就算不定义,也会有一个空的constructor

class Point {
    
}
// 等同于
class Point {
    constructor() {
    }
}

  • 在constructor中return
class Point {
    constructor() {
        return Object.create(null);
    }
}

new Point() instanceof Point
// false
  • class必须使用new
class Point {
    constructor() {
        return Object.create(null);
    }
}
Point();
// Class constructor Point cannot be invoked without 'new'

getter和setter

getter和setter就是拦截器,在做某个操作的时候,可以添加一些自定义的东西。

class Point{
    constructor() {
        // ...
    }
    get x() {
        console.log('getter');
    }
    set x(val) {
        console.log(`setter: ${val}`)
    }
}
const p = new Point();
p.x = 1;
// setter: 1
p.x
// getter

注意点

  • 严格模式

class内部默认就是严格模式。

  • 不存在变量提升
new Point(); // SyntaxError: Identifier 'Point' has already been declared
class Point{}
  • name属性

类是对ES5构造函数的一层封装,所以很多属性都被class继承,包括name这个属性。

class Point{}
Point.name  // Point
  • this的指向问题

正常情况下,this的指向都是类的实例。但是当你单独把其中的方法拿出来调用,那么就会发生报错。

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    print() {
        console.log(this);
        console.log(`x: ${this.x},y: ${this.y}`);
    }
}
const p = new Point();
let {print} = p;
print();

上述例子中,输出的this是undefined。因为this会指向当前函数运行的环境之下,但是class内部定义了严格模式,所以this为undefined。

静态方法和静态属性

  • 静态方法

静态方法是指class上的方法不会被实例继承。关键词——static

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    static print() {
        console.log(this);
        console.log(`x: ${this.x},y: ${this.y}`);
    }
}
const p = new Point();
p.print(); // p.print is not a function
Point.print(); // x: undefined,y: undefined
  • 静态属性

静态属性并没有static这个关键词。

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    static print() {
        console.log(this);
        console.log(`x: ${this.x},y: ${this.y}`);
    }
}
Point.z = 1;
const p = new Point();
p.z //undefined

实例属性的新写法

当一个属性值并没有在初始化的时候赋值,我们可以像下面那么写:

class Point{
    constructor() {
        this.x = 1;
        this.y = 2;
    }
}

// 等同于

class Point{
    x = 1;
    y = 2;
}

总结

这一篇整理了class的一些基础语法。下一篇将会整理class的继承相关。