JavaScript的class只是语法糖,面向对象取决于是否用封装、继承、多态组织代码;实例属性须在constructor中初始化,方法挂载原型,私有字段用#,多态依赖鸭子类型而非类型系统。

JavaScript 本身没有 class 关键字的年代就支持面向对象,现在有了 class 也只是语法糖——真正决定是否“面向对象”的,是你是否在用封装、继承、多态的思路组织代码,而不是有没有 new 或 extends。
用 class 声明构造逻辑,但别把它当 Java 类用
class 在 JavaScript 中不创建类型系统,它只是 function 的包装。实例的原型链依然指向 MyClass.prototype,所有方法都挂载在原型上,而非每个实例独有一份。
实操建议:
JS特效就是网页中实现的特殊效果或者特殊的功能的一种技术,是用网页脚本(javascript)来编写制作动态特殊效果,比如图片切换,渐变等等,它为网页活跃了网页的气氛,有时候会起到一定的亲切力。务(控制台应用程序、桌面应用程序、WEB应用程序等)
- 把实例属性写在
constructor内(如this.name = name),否则容易误以为是“类字段”而漏初始化 - 避免在
class中直接写function表达式作为方法(如method = () => {}),这会破坏原型链,且无法被子类super.method()正确调用 - 静态方法用
static,但它不能访问this实例,只适合工具逻辑(如User.createAdmin())
class User {
constructor(name) {
this.name = name; // ✅ 实例属性必须在这里赋值
}
greet() {
return `Hello, ${this.name}`;
}
static isUser(obj) {
return obj instanceof User;
}
}
继承要小心 super() 调用时机和 this 绑定
子类构造函数中,必须在使用 this 前调用 super();否则会报 ReferenceError: Must call super constructor in derived class before accessing 'this'。
立即学习“Java免费学习笔记(深入)”;
常见错误现象:
- 忘记
super()→ 直接报错退出 -
super()放在this之后 → 同样报错 - 用箭头函数重写父类方法 →
this指向外层作用域,不是当前实例
实操建议:
- 子类
constructor第一行就写super(...args) - 想复用父类逻辑,用
super.methodName(),不要手动绑定Parent.prototype.methodName.call(this) - 如果需要修改父类方法行为,优先用
super调用再处理,而不是完全覆盖
“私有”不是靠命名约定,而是靠 # 字段或闭包
下划线前缀(如 _id)只是提示,无法阻止外部读写。# 开头的字段才是真私有:语法强制不可访问,且不会出现在 for...in、Object.keys() 或 JSON.stringify() 中。
实操建议:
- 用
#字段存敏感状态(如#token、#balance),它比Symbol或闭包更简洁、可读性更高 - 私有字段必须在
constructor或字段声明处初始化(class A { #x = 0; }),不能动态添加 - 若需兼容旧环境(如 IE 或 Node.js this 的方法
class BankAccount {
#balance = 0;
constructor(initial) {
this.#balance = initial;
}
deposit(amount) {
this.#balance += amount; // ✅ 可访问
}
getBalance() {
return this.#balance; // ✅ 可返回
}
}
// new BankAccount(100).#balance // ❌ SyntaxError
多态靠运行时判定,不是类型声明
JavaScript 没有接口或抽象类语法,所谓“多态”就是:同一段代码(如 draw(shape))能接受不同结构的对象,并根据其实际方法存在与否或返回值做分支处理。
实操建议:
- 优先用“鸭子类型”:检查对象是否有某方法(
if ('render' in obj && typeof obj.render === 'function')),而不是instanceof - 避免深度依赖继承链实现多态;组合(
class Button { constructor(renderer) { this.renderer = renderer; })往往比继承更灵活 - 用 TypeScript 的
interface或 JSDoc 的@typedef做契约提示,但别当成运行时保障
真正难的不是写出 class,而是判断什么时候不该用 class——比如配置对象、纯数据容器、一次性的策略函数,用字面量或函数更轻量。










