【ES6】带你深入理解class语法

189 阅读3分钟

class是什么

在ES6中,class关键字提供了一种更简洁、更易读的语法来定义对象的构造函数和方法。虽然在语法上看起来更像是面向对象编程中的类,但实际上,class本质上仍然是基于函数(function)的。 这意味着class所定义的类,最终在JavaScript引擎中仍然被转换为函数。

class的基本语法

ES5中定义对象

在ES5中定义对象通常使用对象字面量(Object literals)或者构造函数来实现。

1. 使用对象字面量

对象字面量是一种简洁的表示方式,可以直接在代码中创建对象。以下是一个示例:

var person = {
  firstName: "John",
  lastName: "Doe",
  fullName: function() {
    return this.firstName + " " + this.lastName;
  }
};

console.log(person.fullName()); // 输出:John Doe

在上面的示例中,person对象包含了firstNamelastNamefullName三个属性,其中fullName是一个函数。

2. 构造函数

  //构造函数
  function Person(name, age) {
    this.name = name;
    this.age = age;
  }
  Person.prototype.say = function () {
    console.log("你好", this.name, this.age);
  };
  let p = new Person("张三", 18);
  console.log(p); //Person {name: "张三", age: 18}

在上面的示例中,我们首先定义了一个名为Person的构造函数,通过this关键字为对象实例添加属性。然后,通过给Person.prototype对象添加方法,实现了原型方法的定义。最后,通过new关键字创建了一个个Person对象的实例。

ES6使用class定义对象

  //class 本质依旧是function
  class Person {
    //默认会有一个空的constructor()构造函数
    constructor(name, age) {
      this.name = name;
      this.age = age;
    }
    //class类中的方法 默认都是定义在原型上,不需要function关键字
    say() {
      console.log("你好", this.name, this.age);
    }
  }

  let p = new Person("张三", 18);
  p.say(); //"你好 张三 18"
  console.log(p); //Person {name: "张三", age: 18}
  console.log(p.name); //"张三"

我们可以看见定义方法不再需要function关键字,同时class内部默认会有一个constructor()

继承

ES6的Class语法支持继承,使得类之间可以建立父子关系。通过extends关键字可以实现类的继承,子类可以继承父类的属性和方法。

  //继承
  class Student extends Person {
    constructor(name, age, score) {
      //super() 表示调用父类的构造函数
      super(name, age);
      //自己的属性
      this.score = score;
    }
  }
  let s = new Student("张三", 18, 100);
  console.log(s); //Student {name: "张三", age: 18, score: 100}

需要注意只有调用super()之后,才可以使用this来定义自己的实例属性。 错误示例:

  class Student extends Person {
    constructor(name, age, score) {
      this.score = score;
      super(name, age);
    }
  }
  let s = new Student("张三", 18, 100);
  console.log(s);

会抛出错误。

image.png

get和set属性

ES6的Class还支持Getter和Setter,通过getset关键字可以定义类的属性访问器。

class Person {
  constructor(name, age) {
    this._name = name;
    this._age = age;
  }
  get name() {
    console.log("get");
    return this._name; // 返回存储在 _name 中的值
  }
  //set
  set name(value) {
    console.log("set");
    if(){
        //做一些判断
    }
    this._name = value; // 将传入的值存储到 _name 中
  }
}
let p = new Person("张三", 18);
console.log(p); // 输出:Person { _name: "张三", age: 18 }
console.log(p.name); // 输出:get   张三
p.name = "李四"; // 输出:set
console.log(p.name); // 输出:get   李四

class的静态方法/方法

ES6的Class支持静态方法。静态方法属于类本身,而不是类的实例,通过在方法前加上static关键字来定义。

  class Person {
    constructor(name, age) {
      this.name = name;
      this.age = age;
    }
    // 静态属性
    static type = "human";
    // 静态方法
    static showName() {
      console.log(this.name);
    }
  }
  //调用静态属性
  console.log(Person.type);
  //调用静态方法
  Person.showName();

总结

ES6的Class语法相比传统的原型继承具有许多优势:

  • 语法更加简洁明了,更符合传统面向对象编程的思维方式。
  • 支持了类的继承,使得代码组织更加清晰。
  • 提供了静态方法和属性的支持,更好地满足了一些特殊需求。
  • 支持Getter和Setter,使得属性访问更加灵活可控。