Skip to content

class

class 为对象提供了 状态(成员变量)的初始值 和 行为(成员函数或方法)。

class = 对象的 可扩展程序代码模版 = 状态(属性,初始值) + 行为(方法,也就是函数)

class 不需要逗号,

js
class MyClass {
  // 需要 polyfill
  prop = value; // 属性

  static staticProp = value;

  constructor(...) { // 构造器
    // ...
  }

  method(...) {} // method

  get something(...) {} // getter 方法
  set something(...) {} // setter 方法

  [Symbol.iterator]() {} // 有计算名称(computed name)的方法(此处为 symbol)

  static staticMethod() { }
}

本质

js
// 这里是方便理解的伪代码

function MyClass() {}

MyClass.prototype = {
  constructor: MyClass,

  method() {},
  get something() {},
  set something() {},
  [Symbol.iterator]() {}
};

MyClass.staticProp = '';

MyClass.staticMethod(){}

通过 class 创建的函数具有一些特性

  1. use strict
  2. enumerable false
  3. [[IsClassConstructor]] true

tips:Object.getOwnPropertyDescriptors( MyClass.prototype )

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

字段

字段 需要 需要 polyfill

字段 是挂在 实例上的

字段 可以用于 bind this

js
class {
    method = () => {}
}

继承

原型链。

extends 后可以指定任意表达式。

继承类的 constructor 必须调用 super,否则将会报错!

super

js
let animal = {
  eat() {
    alert(`eats.`);
  },
};

let rabbit = {
  __proto__: animal,
  eat() {
    this.__proto__.eat.call(this); // (*)
  },
};

let longEar = {
  __proto__: rabbit,
  eat() {
    this.__proto__.eat.call(this); // (**)
  },
};

longEar.eat(); // Error: Maximum call stack size exceeded

this 是不知道 继承关系的,所以会一直死循环。

[[HomeObject]],指向自身,处理 super

函数 不是 方法

函数是没有 [[HomeObject]]

js
let animal = {

  eat: function() { }
  eat() { }

};

虽然二者看似一样,但是实际上差很多!

错误的 [[HomeObject]] 会导致很多内部问题!

[[HomeObject]]应该是对象方法都有的

表达式

类 的本质 就是 函数,所以 class 也支持表达式,也是一等公民

封装

内部接口与外部接口的划分被称为 封装。

用户 并不关心“内部”实现,并且将“内部”暴露给 “用户” 也不是一个明智的选择。

私有

  1. _
  2. #

_ 是约定俗成,并不受语言保护。

# 需要 polyfills。
# 支持属性 和 方法。

# 是私有的,所以 Object.getOwnPropertyDescriptors 并不能获取到相关信息。它只能内部使用。