ES6 - Class

采用面向对象编程(OOP)时,需要用(class)去描述一类对象,用来作为创建这类对象的模板,当某个对象需要在类中被创造出来时,类的构造函数就会运行来创建这个实例

构造函数

ES6 之前使用构造函数的方式来生成实例对象,举个例子:

function Person(name) {
  this.name = name;
  this.greeting = function() {
    alert('Hi! I\'m ' + this.name + '.');
  };
}

通过函数定义了一类人,这类人有 name 属性和 greeting 方法,当我们通过构造函数去创建实例时,每一个创建出来的人都会拥有这两个属性:

var person = new Person('Bob');
person.name // Bob
person.greeting() // Hi! I'm Bob.

ES6 提供了类的语法糖 class,其本质上就是一个特殊的函数:

class Person{
  // 构造函数,通过 new 命令生成对象实例时,自动调用该方法
  constructor(name){
      // 定义属性
      this.name = name;
  }
  // 原型方法
  greeting() {
      alert('Hi! I\'m ' + this.name + '.');
  };
  // 静态方法
  static greeting2(){
      alert('Hi!');
  }
}

子类

对象可以被拓展来增加新的属性或方法,extends 用来创建子类,子类会继承父类的属性和方法:

class Boy extends Person {
    speak(){
        console.log('speaking');
    }
}
const boy = new Boy('Blob');

boy.name // Bob
boy.greeting() // Hi! I'm Bob.
boy.speak() // speaking

子类的构造函数必须执行一次 super(),如果不写构造函数,则会默认添加

class Boy extends Person {
    constructor(){
       super(); // 相当于 Person.call(this)
    }
  
    callGreeting(){
       super.greeting(); // 可以调用父类的方法
    }
}

getter/setter

通过 getter / setter 可以改变属性的赋值和读取的行为:

class Animal {
  constructor(name) {
    this.name = name;
  }
  get name() {
    return 'Jack';
  }
  set name(value) {
    console.log('setter: ' + value);
  }
}

let a = new Animal('Kitty'); // setter: Kitty
a.name = 'Tom'; // setter: Tom
console.log(a.name); // Jack

静态方法/属性

静态方法

通过 static 修饰符修饰的方法称作静态方法,不进行实例化也能被调用,但是通过实例化的对象进行调用会报错:

class Animal {
  static isAnimal(a) {
    return a instanceof Animal;
  }
}

let a = new Animal('Jack');
Animal.isAnimal(a); // true
a.isAnimal(a); // TypeError: a.isAnimal is not a function

注意点:

  1. 父类的静态方法能够被子类继承。

    class Foo {
        static classMethod() {
            return 'hello';
        }
    }
    class Bar extends Foo {}
    Bar.classMethod(); // 'hello'
    
  2. 静态方法调用同一个类中的其他静态方法可使用this关键字。

    class StaticMethodCall {
        static staticMethod() {
            return 'Static method has been called';
        }
        static anotherStaticMethod() {
            return this.staticMethod() + ' from another static method';
        }
    }
    console.log(StaticMethodCall.staticMethod())
    // 'Static method has been called'
    
    console.log(StaticMethodCall.anotherStaticMethod())
    // 'Static method has been called from another static method'
    
  3. 非静态方法不能使用this关键字来访问静态方法,而是需要使用类名去访问。

    class StaticMethodCall {
        constructor() {
            console.log(StaticMethodCall.staticMethod());
            // 'static method has been called.'
            console.log(this.constructor.staticMethod());
            // 'static method has been called.'
            console.log(this.staticMethod());
            // this.staticMethod is not a function
        }
        static staticMethod() {
            return 'static method has been called.';
        }
    }
    
    new StaticMethodCall();
    

静态属性

通过 static 修饰符修饰的变量称作静态属性,和静态方法类似:

class Animal {
  static isAnimal = true
}

let a = new Animal('Jack');
Animal.isAnimal; // true
a.isAnimal; // undefined
作者

BiteByte

发布于

2020-08-08

更新于

2024-11-15

许可协议