# 类是什么

虽然 ES6 提供了 class 关键字用于创建对象,但其终究只是语法糖,底层并未实现。

// ES6 创建类
class Hero {
  constructor() {
    this.name = "张无忌";
    this.sayMe = function () {
      console.log("this is 张无忌");
    };
  }
}

# 类的声明

  1. 类的声明方式

    class name [extends]{
        // class body
    }

    name 表示当前类的名称。此方法不允许再次声明已经存在的类,否则会抛出一个类型错误。

  2. 类的表达方式

    const MyClass = class [className] [extends]{
        // class body
    }

    和函数表达式相同的一点是,类表达式可以是命名也可以是匿名的。如果是命名类表达式,这个名字只能在类体内部才能访问到。

# 构造函数

class Hero {
  constructor() {}
}
  • 在一个类中只能有一个名为 “constructor” 的特殊方法。类中出现多次构造函数 (Constructor) 方法将会抛出一个 SyntaxError 错误。

  • 在一个构造方法中可以使用 Super 关键字来调用一个父类的构造方法。

  • 如果没有显式指定构造方法,则会添加默认的 constructor 方法。

  • 如果不指定一个构造函数( constructor)方法,则使用一个默认的构造函数(constructor)

class Hero {
  constructor() {
    this.name = "张无忌";
    this.say = function () {
      console.log("Im am ", this.name);
    };
  }
}
let hero = new Hero();
hero.say(); //Im am  张无忌

# getter 和 setter

在 “类” 的内部可以使用 get 和 set 关键字,对某个属性设置存值函数取值函数,拦截该属性的存取行为

class Hero {
  constructor() {
    this.v = 100;
  }
  get getV() {
    return this.v;
  }
  set setV(value) {
    this.v = value;
  }
}
var obj = new Hero();
console.log(obj.getV); // 100

# 静态方法

static name(){
    // code
}

在类的内部允许定义静态方法,静态方法不会被添加到当前类的实例中。通过类直接调用此方法。

class Hero {
  constructor() {
    this.name = "张无忌";
  }
  static sayMe() {
    console.log("this is 张无忌");
  }
}
Hero.sayMe(); //this is 张无忌

在一个静态方法中调用另外一个静态方法。

class Hero {
  constructor() {
    this.name = "张无忌";
    this.sayMe = () => {
      console.log("this is ", this.name);
      // 在 constructor 中调用静态方法是类名直接调用
      Hero.sayYou();
    };
  }
  // 不可枚举的方法
  toString() {
    console.log("name toString", this.name);
  }
  static sayYou() {
    console.log("this is sayYou");
  }
    static sayHe() {
    // 在静态方法中可以使用类名,也可以使用 this
    // Hero.sayYou();
    this.sayYou();
  }
}
let hero = new Hero();
hero.sayMe();
Hero.sayHe();
  1. constructor 中只能通过类名调用
  2. 在静态方法中可以通过类名调用也可以通过 this 调用。

# 类的继承

类在继承时使用关键字 extends 关键字即可。

class Child extends Parent {
  constructor() {
    super(); //super 指向当前子类的父类的构造器
    this.age = 18;
  }
}

继承的类会继承类的方法,静态方法和构造函数。

class Parent {
  constructor() {
    this.name = "parent";
    this.sayMe = function () {
      console.log("this is sayMe");
    };
  }
  sayYou() {
    console.log("this is sayyou");
  }
  static staticMethod() {
    console.log("this is staticMethod");
  }
}
// 声明 child 类时,指定 child 类作为 Parent 类的子类
class Child extends Parent {
  constructor() {
    super(); //super 指向当前子类的父类的构造器
    this.age = 18;
  }
}
let child = new Child();
console.log(child); // 
child.sayYou();
Child.staticMethod();

image-20201027170309833

# 继承实例

class myDate extends Date {
  constructor() {
    super();
  }
  getFormattedDate() {
    let months = [
      "Jan",
      "Feb",
      "Mar",
      "Apr",
      "May",
      "Jun",
      "Jul",
      "Aug",
      "Sep",
      "Oct",
      "Nov",
      "Dec",
    ];
    return `${this.getDate()}-${months[this.getMonth()]}-${this.getFullYear()}`;
  }
}
let date = new myDate();
console.log(date.getFormattedDate()); // 27-Oct-2020

通过继承一个 Date 对象,对其扩展自己的方法。

# super 关键字

  1. super 关键字作为函数调用时,代表父类的构造函数。ES6 要求子类的构造函数必须执行一次 super 函数

    super 虽然代表了父类 A 的构造函数,但是返回的是子类 B 的实例。

  2. super 当作对象时,在普通方法中,指向父类的原型对象。在静态方法中,指向父类。

    由于 super 指向父类的原型对象,所以定义在父类实例上的方法或属性,是无法通过 super 调用的。

# 类的完整示例

// 定义一个类
class Parent {
  // 表示当前类的构造器(如果省略,JavaScript 会自动生成)
  constructor(name) {
    this.name = name;
  }
  // 类的方法,不是原型方法
  toString() {
    console.log("this is parent toString");
    return "this is parent toString";
  }
  // 由当前类直接调用的方法
  static staticMethod() {
    console.log("this is parent static");
    return "this is parent static";
  }
  sayMe() {
    console.log("this is parent sayMe");
    return "this is parent sayMe";
  }
}
// 类具有原型
Parent.prototype.sayYou = function () {
  console.log("this is parent sayYou");
  return "this is parent sayYou";
};
//
class Child extends Parent {
  constructor(name, age) {
    super(name); // 指向父类构造器
    this.age = age;
    super.sayMe(); // 指向父类的实例对象
    super.sayYou(); // 指向父类的实例对象
  }
  toString() {
    console.log("this is child toString", super.toString());
  }
  static staticMethod() {
    console.log("this is child static", super.staticMethod());
  }
}
let child = new Child("XiaoKang", 18);
console.log(child);
// 将子类和父类的相同方法同时调用
child.toString();
Child.staticMethod();
更新于

请我喝[茶]~( ̄▽ ̄)~*

Dreamy.TZK 微信支付

微信支付

Dreamy.TZK 支付宝

支付宝