JavaScript中如何创建类?ES6 class类定义与继承怎么用?

来源:AI编程作者:深圳程序员头衔:程序员
导读:本期聚焦于深圳程序员创作的《JavaScript中如何创建类?ES6 class类定义与继承怎么用?》,敬请观看详情。class 并不是 JavaScript 突然多出来的全新对象模型,它的底层依然是构造函数与原型链。ES6 引入 class 关键字后,定义类、继承、静态成员都变得更加直观,但也容易让人忽略原型机制。本文围绕 class 基本语法、constructor 构造器、extends 继承、super 调用顺序、静态方法与私有字段展开,通过对比传统原型写法和 class 写法说明差异,并指出 class 声明提升、严格模式、this 丢失等常见问题。此外还会介绍私有字段的封装方式,以及 getter、setter 和静态方法在继承中的表现。掌握这些细节后,无论是写业务组件还是封装工具库,都能更准确地控制对象创建、属性访问与继承行为,少踩一些由语法糖带来的隐蔽陷阱。

使用 JavaScript 创建类有多种方式,早期主要依靠构造函数配合原型对象,ES6 之后新增的 class 关键字让代码结构更加清晰。class 本质上并非一套全新的对象模型,而是对构造函数和原型链写法的封装。理解这一点,后续处理继承、this 绑定和私有状态时会更有方向。

JavaScript中如何创建类?ES6 class类定义与继承怎么用?

一、从构造函数到 class:语法糖背后的原型机制

在 ES6 之前,创建一个“类”通常需要定义一个构造函数,然后把公共方法挂到 prototype 对象上。这种写法虽然可行,但代码分散,手动管理原型链也容易出错。class 关键字把构造过程、实例方法和静态成员集中到一个代码块中,阅读成本更低。

传统构造函数的写法如下:

function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.sayHello = function() {
  console.log('Hello, I am ' + this.name);
};
const p = new Person('张三', 28);
p.sayHello();

使用 class 改造后,constructor 方法承担构造函数职责,其他方法自动成为原型方法。下面的示例实现同样的功能:

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHello() {
    console.log('Hello, I am ' + this.name);
  }
}
const p = new Person('张三', 28);
p.sayHello();

两种写法产生的结果基本一致:Person.prototype.sayHello 都会成为可被实例调用的原型方法。区别在于 class 声明不会提升,必须先在代码中定义再使用;而函数声明则会提升。此外,class 内部默认运行在严格模式下,方法内部的 this 不会意外指向全局对象。

需要注意的是,class 并不是一种新的数据类型,typeof Person 返回的值仍然是 function。这说明 class 本质上是函数的一种特殊写法,只是语法更加贴近传统面向对象语言。

二、extends 继承与 super 的执行顺序

继承是类的重要特性。通过 extends 关键字,子类可以继承父类的实例方法和静态方法,还可以在自己的构造函数中扩展属性。当子类定义了 constructor 时,第一行必须调用 super(...),之后才能使用 this。这一限制是为了保证父类构造函数先完成初始化,避免子类操作尚未创建的实例。如果不显式定义 constructor,子类会自动调用 super(...args) 并传入所有参数。

下面的代码展示了继承的基本用法,同时演示了方法覆写与通过 super.method() 调用父类实现:

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(this.name + ' makes a sound.');
  }
  static info() {
    return 'Animal class';
  }
}
class Dog extends Animal {
  constructor(name, breed) {
    super(name);
    this.breed = breed;
  }
  speak() {
    super.speak();
    console.log(this.name + ' barks.');
  }
}
const dog = new Dog('旺财', '金毛');
dog.speak();
console.log(Dog.info());

运行这段代码会先输出“旺财 makes a sound.”,再输出“旺财 barks.”,最后打印“Animal class”。可以看到 super.speak() 成功调用了父类原型上的方法,而静态方法 info 也被子类继承。继承链上静态方法同样可用,这是很多开发者容易忽略的细节。

还有一个容易混淆的点:super 作为函数调用时返回的是子类实例,并且会初始化父类构造函数;作为对象访问时则指向父类的原型对象。两者虽然都用 super 表达,但语义完全不同。如果在子类 constructor 中先使用 this 再调用 super,会直接抛出 ReferenceError,这类错误在调试时比较常见。

三、静态成员、私有字段与常见使用误区

静态成员通过 static 关键字定义,只能由类本身访问,实例无法调用。静态方法常用于编写工具函数,例如日期格式化、数学计算等。静态方法内部的 this 指向类本身而不是实例,因此不要试图在静态方法中访问实例属性。

class DateHelper {
  static formatDate(date) {
    const year = date.getFullYear();
    const month = date.getMonth() + 1;
    return year + '-' + month + '-' + date.getDate();
  }
}
console.log(DateHelper.formatDate(new Date()));

从 ES2022 开始,私有字段使用 # 前缀声明。私有字段只能在类内部访问,外部访问会抛出语法错误。这为封装内部状态提供了原生能力,不再需要借助闭包或 WeakMap 等技巧。下面是一个计数器的例子:

class Counter {
  #count = 0;
  increment() {
    this.#count++;
  }
  get value() {
    return this.#count;
  }
}
const counter = new Counter();
counter.increment();
console.log(counter.value);
console.log(counter.#count);

示例最后一行 counter.#count 在类外部访问会直接报 SyntaxError,这体现了私有字段的强封装性。私有字段与普通属性不同,不能通过 this['#count'] 或 this.#count 之外的方式访问,而且它不会被继承到子类实例的原型链上。

除了语法本身,还有一些实践中频繁出现的误区:一是把 class 当作函数直接调用,比如 Person('张三'),这在严格模式下会报错;二是忘记在子类 constructor 中调用 super;三是在普通函数中提取实例方法导致 this 丢失;四是误以为 class 会改变 JavaScript 的原型继承模型。理解 class 背后的原型机制,才能真正用好这些语法糖,避免隐藏的坑。

JavaScript类ES6 class继承修改时间:2026-10-05 04:25:42

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/1005/65841.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。