本质是构造函数的语法糖 目的是让类的声明与继承更加简洁清晰

声明定义

class

* 使用 new 关键字构造对象实例
* class 定义的方法不能枚举
* class 默认使用严格模式执行

  1. class Human {
  2. constructor(name, age) {
  3. this.name = name;
  4. this.age = age;
  5. };
  6. run() {};
  7. eat() {};
  8. }
  9. var human = new Human("zhangsan", 18);
  10. console.log(Object.keys(human)); // ["name", "age"], 无法遍历方法

构造器

constructor

构造器用于传递对象的初始参数

* 非必须的
* 如果没有显性定义构造函数,系统会自动创建构造函数,并实现继承
* 子构造器必须调用完 super 后才可以使用 this
* 主要目的是纠正 this 指向

  1. class Human {}
  2. /**
  3. * 等效于
  4. * class Human {
  5. * constructor(...args) {
  6. * super(...args);
  7. * }
  8. * }
  9. */
  10. // 传递初始值
  11. class Male {
  12. constructor(name) {
  13. this.name = name;
  14. }
  15. }

静态属性、方法

静态属性和方法是可以被继承使用的

static

* 静态属性、方法是类自身的属性、方法
* 一般情况下,不需要对象属性参与计算的方法可以定义为静态方法

  1. class Human {
  2. static eat() {
  3. console.log("eat");
  4. }
  5. }
  6. var human = new Human();
  7. Human.eat(); // "eat"
  8. human.eat(); // error: human.eat is not a function

访问器

getter / setter

* 类似对象中的属性访问器

  1. class Human {
  2. _name = "zhangsan";
  3. get name() {
  4. return this._name;
  5. }
  6. set name(name) {
  7. this._name = name;
  8. }
  9. }
  10. var human = new Human();
  11. console.log(human.name); // "zhangsan"
  12. human.name = "lisi";
  13. console.log(human.name); // "lisi"

访问控制

* javascript 中没有访问修饰符
* 通过约定实现访问控制的效果

public

公共的、不受保护的属性。 类的内部、外部、继承的子类都可以访问

  1. class Human {
  2. name = "zhangsan";
  3. }
  4. var human = new Human();
  5. console.log(human.name); // "zhangsan"

protected

受保护的属性 类的内部、继承的子类可以访问,类的外部无法访问

* 约定以 _ 开头的变量或方法为受保护的
* 外部通过访问器 setter 修改受保护的属性或方法
*外部通过访问器 getter 访问受保护的属性或方法**

  1. class Human {
  2. _name;
  3. set name(name) {
  4. this._name = name;
  5. }
  6. get name() {
  7. return this._name;
  8. }
  9. }

通过 Symbol 结合访问器定义内部属性、方法名,实现属性保护

* 无法实现完全的受保护,当通过定义的 Symbol 变量访问时,可以访问到。使用新的 Symbol 变量无法访问

  1. const protects = Symbol();
  2. class Human {
  3. constructor() {
  4. this[protects] = {};
  5. this[protects].name = "zhangsan";
  6. }
  7. set name(name) {
  8. this[protects].name = name;
  9. }
  10. get name() {
  11. return this[protects].name;
  12. }
  13. }
  14. var human = new Human();
  15. console.log(human[protects].name); // "zhangsan"
  16. console.log(human.name); // "zhangsan"
  17. console.log(human[Symbol()].name); // error: Cannot read property "name" of undefined

**

通过 WeakMap 定义内部属性、方法名,实现属性保护

* 可以实现完全的受保护

  1. const protects = new WeakMap();
  2. class Human {
  3. constructor() {
  4. protects.set(this, "zhangsan");
  5. }
  6. set name(name) {
  7. protects.set(this, name);
  8. }
  9. get name() {
  10. return protects.get(this);
  11. }
  12. }
  13. var human = new Human();
  14. console.log(human.name); // "zhangsan"

**

private

私有属性 只有类的内部可以访问,类的外部、继承的子类无法访问

* 约定以 # 开头的变量或方法为私有的
*外部通过访问器 setter 修改私有的属性或方法
*
**外部通过访问器 getter 访问私有的属性或方法

  1. class Human {
  2. #name = "zhangsan";
  3. set name(name) {
  4. this.#name = name;
  5. }
  6. get name() {
  7. return this.#name;
  8. }
  9. }
  10. var human = new Human();
  11. console.log(human.name); // 张三

继承

extends

* 继承必须在子类构造函数中调用 super() 执行父类的构造函数

  1. class Human {}
  2. class Male extends Human {
  3. constructor() {
  4. super();
  5. }
  6. }

super

* 指父类引用
* 只能在类或对象的方法中使用,不能在函数中使用

  1. class Human {
  2. run() {
  3. console.log("run");
  4. }
  5. }
  6. class Male extends Human {
  7. constructor() {
  8. super();
  9. }
  10. eat() {
  11. super.run();
  12. }
  13. }
  14. var male = new Male();
  15. male.eat(); // "run"

多继承

* javascript 不能实现多继承
* 使用多个类的方法,可以通过 mixin 混合模式实现

mixin

* 通过 Object.assgin() 将多个类的原型对象中的方法进行合并

  1. class Tool {
  2. sum(nums) {
  3. return nums.reduce((pre, cur) => pre + cur, 0);
  4. }
  5. }
  6. class Item {
  7. #list = [];
  8. constructor(...list) {
  9. this.#list = list;
  10. }
  11. get list() {
  12. return this.#list;
  13. }
  14. }
  15. // 混合操作
  16. Object.assign(Item.prototype, {
  17. sum: Tool.prototype.sum
  18. });
  19. var item = new Item(1, 2, 3, 4, 5);
  20. var total = item.sum(item.list); // 15