JS-学习ES6之- class 的基本用法

时间:2023-01-13 09:45:07

目录

  • 简介
  • constructor 方法
  • 类的实例对象
  • 私有方法和私有属性
  • class 的静态方法
  • class 的静态属性和实例属性
  • new.target 属性

1、简介

JavaScript 语言中,生成实例对象的传统方法是通过构造函数。
ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过 class关键字,可以定义类。

// ES5的方法
function Point (x, y) {
  this.x = x;
  this.y = y;
}

Point.prototype.toString = function () {
  return '(' + this.x + ', ' + this.y + ')';
};

var p = new Point(1, 2);

// ES6的方法
class Point () {
  constructor (x, y) {
    this.x = x;
    this.y = y;
  }

  toString(){
    return '(' + this.x + ', ' + this.y + ')';
  }
}

var p = new Point(1, 2);

构造函数的 prototype 属性,在 ES6 的“类”上面继续存在。事实上,类的所有方法都定义在类的 prototype 属性上面。

2、constructor 方法

constructor 方法是类的默认方法,通过 new 命令生成对象实例时,自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,一个空的 constructor 方法会被默认添加。

class Point {
}

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

3、类的实例对象

生成类的实例对象的写法,与 ES5 完全一样,也是使用 new 命令。

类必须使用 new 调用,否则会报错。

4、类的私有方法和私有属性

ES6 目前还都不支持类的私有方法和私有属性。

目前,有一个提案,为 class 加了私有属性。方法是在属性名之前,使用 # 表示。

class Point {
  #x = 1;
  constructor (x = 0){
    #x = x; // 也可以写成 thi.#x = x
  }

  get x (){
    return #x;
  }
  set x (value){
    #x = value;
  }
}

类的属性名,可以采用表达式。

let methodName = 'getArea';
class Square {
  constructor(length){
    // ...
  }

  [methodName](){
    // ...
  }
}

上面代码中,Square 类的方法名 getArea,是从表达式得到的。

5、class 的静态方法

如果在一个类的方法前面加上了 static 关键字,则表示该方法不会被实例继承,而是直接通过类来调用的。这个方法称为“静态方法”。

class Foo {
  static classMethod() {
    return 'hello';
  }
}

Foo.classMethod() // 'hello'

var foo = new Foo();
foo.classMethod()
// TypeError: foo.classMethod is not a function

注意,如果静态方法包含 this 关键字,这个 this 指的是类,而不是实例。

class Foo {
  static bar (count) {
    this.count = count; // this 指向 Foo 类
  }
}

父类的静态方法,可以被子类继承。静态方法也是可以从 super 对象上调用的。

5、class 的静态属性

静态属性指的是 Class 本身的属性,即 Class.propName,而不是定义在实例对象(this)上的属性。

ES6 明确规定,Class 内部只有静态方法,没有静态属性。

class Foo {
}

Foo.prop = 1;
Foo.prop // 1

上面的写法为 Foo 类定义了一个静态属性 prop 。目前,只有这种写法可行。

但是目前有一个提案,提供了 class 静态属性的方法,使用 static 关键字。

class MyClass {
  static myStaticProp = 42; // MyClass 的静态属性

  constructor() {
    console.log(MyClass.myStaticProp); // 42
  }
}

当上述代码中的 static 去掉之后,即会实例的属性。

class MyClass {
  myStaticProp = 42; // 实例的属性

  constructor() {

  }
}

// 相当于

class MyClass {

  constructor() {
    this.myStaticProp = 42; // 实例的属性
  }
}

6、new.target 属性

new 是从构造函数生成实例对象的命令。ES6 为 new 命令引入了一个 new.target 属性,该属性一般用在构造函数之中,返回 new 命令作用于的那个构造函数。如果构造函数不是通过 new 命令调用的, new.target 会返回 undefined ,因此这个属性可以用来确定构造函数是怎么调用的。

需要注意的是,子类继承父类时,new.target 会返回子类。