javascript ES6的类(class)如何使用?【教程】

10次阅读

es6class是语法糖,基于原型继承;用class声明、constructor初始化;不提升;需用extends和super()实现继承;私有成员用#前缀;类字段在super()后初始化。

javascript ES6的类(class)如何使用?【教程】

ES6 的 class 不是新对象模型,只是语法糖——它背后仍是基于原型的继承,不能替代对 prototype构造函数的理解。

如何定义一个基础类?

class 关键字声明,内部用 constructor 定义初始化逻辑。注意:类声明不会被提升(hoisted),必须先声明后使用。

常见错误:ReferenceError: Cannot access 'MyClass' before initialization —— 就是因为把它当成了 function 声明来用了。

  • constructor 是可选的;没写时会默认提供一个空构造函数
  • 类体中只能写方法(含 get/set)、静态方法(Static)和字段(public 或 #private),不能写语句或表达式
  • 类名在类内部可通过 constructor.name 获取,但不能直接用类名递归调用自身(比如在 constructor 里写 new MyClass() 会报错,除非类名已存在且在作用域外)

怎么实现继承?extendssuper() 必须一起用

子类构造函数中若定义了 constructor,就必须显式调用 super(),否则会报 ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

立即学习Java免费学习笔记(深入)”;

原因:super() 负责初始化 this,不调就无法访问实例属性。

  • super() 必须在 this 之前调用,哪怕只调一次
  • super 也可作为对象调用父类方法:super.methodName()
  • 静态方法也能被 extends 继承,但需通过 super 在子类静态方法中调用父类静态方法

私有字段和方法怎么写?用 # 前缀,不是 private 关键字

ES6 没有 private 关键字;真正的私有成员必须以 # 开头,且只能在类内部访问。试图从外部读写 obj.#field 会直接报 SyntaxErrorTypeError

注意:# 字段不可枚举、不可代理、不可反射(Reflect.ownKeys() 不返回它们),也不参与 jsON.stringify()

  • 私有方法也必须用 # 前缀,且只能被同个类内的其他方法调用
  • 不能用字符串拼接绕过:比如 this['#' + 'name'] 无效
  • 私有字段名必须在类定义时就确定,不能动态生成(#[key] 不合法)

类字段(class fields)的陷阱:不在 constructor 里初始化时,顺序很重要

类字段(如 value = 123)会在 constructor 执行前初始化,但它们的执行顺序是自上而下——如果字段依赖尚未声明的变量,就会报 ReferenceError

例如:foo = this.bar(); bar() { return 'ok'; } 是合法的;但 foo = this.baz; baz = 'ok'; 会出错,因为 baz 还未赋值。

  • 字段初始化表达式中可以调用方法,但不能引用尚未声明的字段
  • 字段初始化发生在 super() 之后、constructor 函数体之前
  • 如果同时有 constructor 和字段初始化,建议把复杂逻辑收进 constructor,避免隐式执行顺序问题

真正容易被忽略的是:类不是“类型系统”,typescriptclass 会编译成 ES6 类,但 javaScript 运行时根本不检查类型;所有 instanceoftypeof、原型链操作,都还是原来那套。别指望 class 自动带来封装或类型安全。

text=ZqhQzanResources