JavaScript类如何定义_与构造函数有什么区别【教程】

JavaScript类是构造函数的语法糖,基于原型链实现;类声明不提升,方法不可枚举且自动严格模式;constructor非构造函数本身,而是new触发后自动调用的初始化方法。

JavaScript 类定义用 class 关键字,本质是构造函数的语法糖

ES6 的 class 不是全新机制,底层仍基于原型链和函数对象。当你写 class Person { constructor(name) { this.name = name; } },JS 引擎实际会生成一个带 constructor 属性的函数,并把方法挂到 Person.prototype 上。

关键区别在于:类声明不会被提升(ReferenceError),而函数声明会被提升;类内部所有方法默认是不可枚举的,且严格模式下自动启用。

constructor 是类中唯一必需的方法,但不是“构造函数”本身

很多人误以为 constructor 就是传统意义上的“构造函数”,其实它只是类初始化时自动调用的特殊方法。真正的构造行为由 new 操作符触发,它会:

  • 创建一个空对象,绑定 this 到该对象
  • 执行 constructor 中的代码
  • 返回该对象(除非显式返回另一个对象)

如果省略 constructor,JS 会自动插入一个空的:

constructor() {}

注意:constructor 不能是箭头函数,也不能用 return 返回原始值(如 return 42),否则会报 TypeError: Class constructor cannot be invoked without 'new'

类中定义方法不加 function 关键字,且不能用 var/let/const 声明

这是初学者最常出错的地方。类体中只允许出现:

  • constructor 方法
  • 普通方法(如 sayHello() { ... }
  • getter/setter(如 get age() { return this._age; }
  • 静态方法(用 static 修饰)
  • 公有字段(ES2025+,如 name = 'default';

以下写法全部非法:

class Bad {
  function say() {}        // ❌ 语法错误
  const x = 1;              // ❌ 语法错误
  var y = 2;                // ❌ 语法错误
  #private = 3;             // ✅ 私有字段(需用 #)
}

方法名不能叫 constructor(除构造器本身外),也不能与已有属性同名导致覆盖。

继承时 super() 必须在 this 之前调用

子类构造器中若使用 this,必须先调用 super()。否则会报 ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor

super() 的作用是调用父类 constructor,完成父类实例初始化。它等价于 ParentClass.prototype.constructor.call(this, ...args)

常见错误场景:

  • 忘记写 super() —— 直接报错
  • super() 前访问 this —— 报错
  • super() 传参错误(比如父类需要参数却没传)—— 运行时逻辑异常,但不报语法错

示例:

class Animal {
  constructor(name) {
    this.name = name;
  }
}
class Dog extends Ani

mal { constructor(name, breed) { super(name); // ✅ 必须第一行 this.breed = breed; } }

类的继承链条最终指向 Object,但你不能直接 extends null(会报 SyntaxError),除非用函数方式手动设置原型。