JavaScript(Class)|青训营笔记

91 阅读2分钟

JavaScript(Class)|青训营笔记

这是我参与「第四届青训营 」笔记创作活动的的第4天

Class

1.class与function

class语法糖之前,JavaScript使用function来定义对象
如下比较

function point(x,y) {
  this.x = x;
  this.y = y;
  
  point.prototype.get = function() {
    return `(${this.x},${this.y})`;
  }
}

采用class的方法

class point {
  constructor(x,y) {
    this.x = x;
    this.y = y;
  }

  get() {
    return `(${this.x},${this.y})`;
  }
}

其中 constructor()写法就是构造方法,this代表实例对象,定义的get()方法就和 function中的 point.prototype.get()一样

class Point {
  // ...
}

typeof Point // "function"
Point === Point.prototype.constructor // true

类的方法都定义在prototype对象上,所以类的新方法也可以通过Object.assign()方法一次添加很多方法

class Point {
  constructor(){
    // ...
  }
}

Object.assign(Point.prototype, {
  toString(){},
  toValue(){}
});

2.类的属性

2.1 constructor()方法

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

2.2 类的实例

通过 new 关键字生成,class默认是严格模式

2.3 实例属性的新写法

class Point {
  constructor() {
    this.counter = 0;
  }
  getCounter() {
    return this.counter;
  }
}
// 新写法
class Point2 {
  counter = 0;
  getCounter() {
    return this.counter;
  }
}

属性可以定义在类的最顶层,其它不变,不需要再写 this

3. 取值函数(getter) 和存值函数 (setter)

  • 可以使用 get 和 set 关键字,对某个属性设置取值函数(getter) 和存值函数 (setter)
class MyClass {
  constructor() {
    // ...
  }
  get prop() {
    return 'getter';
  }
  set prop(value) {
    console.log('setter: '+value);
  }
}

let inst = new MyClass();
inst.prop = 123;
// setter: 123
inst.prop
// 'getter'
  • 私有属性也可以设置
class MyClass {
  #name = '李华';
  constructor() {
    // ...
  }
  get name() {
    return this.#name;
  }

  set name(name) {
    this.#name = name; 
  }
}

let P = new MyClass();
P.name = '碇真嗣';
// #name = '碇真嗣'
P.name
// '碇真嗣'

4. 静态方法与静态属性

4.1静态方法

在方法前添加 static 关键字,该方法不会被实例继承,而是直接通过类调用

class foo {
  static Hello() {
    return 'Hello';
  }
}
foo.Hello();  // 'Hello'
const F = new foo();
f.Hello();
// TypeError: F.Hello is not a function
  • 父类的静态方法可以被字类继承

4.2 静态属性

class本身的属性

class Foo {
  static bar = '456';
}
Foo.prop = 123;
console.log(Foo.prop); // 123
console.log(Foo.bar); // '456'

5.私有方法和私有属性

  • 早期通过 _prop(下划线命名来表示私有属性,但不是真正的私有,还是可以访问到) 或者 symbol 来实现
  • ES2022正式添加了私有属性 在属性名前用 # 表示
class Counter {
  #counter = 0;

  // 私有方法
  #increment() {
    this.#counter ++;
  }
}
const P = new Counter();
P.#counter; // 报错
  • 私有属性也可以设置getter setter方法

6.class的继承

  • 通过extends关键字实现继承
  • 字类必须在 constructor()方法中调用 super()方法,来继承父类同样的实例属性和方法
  • 私有属性字类不可访问
class Father {
  #counter = 0;
 
  #getCounter() {
    return this.#counter;
  }

  getCounter() {
    return this.#getCounter();
  }

}

class Son extends Father {
  constructor() {
    super()
  }

  getFun() {
    return this.getCounter();
  }
}

const s = new Son();
console.log(s.getFun()); // 0

可以通过父类的函数获取到私有属性