当前位置: 首页 > 新闻动态 > 网络资讯

javascript面向对象编程如何理解_类和继承怎样实现【教程】

作者:夜晨 浏览: 发布日期:2026-01-27
[导读]:JavaScript的class只是语法糖,未改变原型本质;它要求super()必须首行调用、不提升、方法不可枚举,继承仍基于[[Prototype]]链,核心在于对象创建时的原型关联、属性查找与this绑定。
JavaScript 的 class 只是语法糖,未改变原型本质;它要求 super() 必须首行调用、不提升、方法不可枚举,继承仍基于 [[Prototype]] 链,核心在于对象创建时的原型关联、属性查找与 this 绑定。

JavaScript 里 class 不是“新类型”,只是语法糖

ES6 的 class 关键字没有改变 JavaScript 基于原型的本质。它只是把原本用 function + prototype 写的构造逻辑,包装成更接近传统 OOP 语言的写法。如果你试图用 Java/C# 的类模型去套,很容易在动态性、this 绑定、继承链这些地方掉坑。

实操建议:

  • class 声明不会被提升(hoisted),必须先声明再使用,否则报 ReferenceError
  • 类体内只能写方法定义、get/setstatic 成员,不能写普通变量或表达式
  • 所有方法默认不可枚举(enumerable: false),这点和手动挂到 prototype 上一致
  • 类内部不支持私有字段语法(如 #private)在旧环境会直接报错,需确认目标运行时是否支持

extendssuper() 实现继承时,super() 必须调用

子类构造函数中若定义了 constructor,就必须显式调用 super(),否则会报 ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor。这不是可选项,是引擎强制的时序约束——因为子类实例的 this 依赖父类构造器初始化内部槽位(如 [[Prototype]])。

常见错误场景:

  • 只写了 super() 但没传参,导致父类接收不到必要参数
  • super() 前访问 this,哪怕只是 console.log(this) 也会立即报错
  • 误以为 super.method() 等价于 Parent.prototype.method.call(this),其实前者在箭头函数中会丢失 this 绑定上下文

示例:

class Animal {
  constructor(name) {
    this.name = name;
  }
}
class Dog extends Animal {
  constructor(name, breed) {
    super(name); // ✅ 必须且必须在第一行
    this.breed = breed;
  }
}

原型链继承 vs 类继承:关键差异在 instanceofObject.getPrototypeOf()

class 定义的继承,底层仍靠修改 [[Prototype]] 链,所以 instanceofObject.getPrototypeOf() 的行为和手写原型链一致。但有个易忽略点:子类的 constructor 属性默认指向自身,而它的 prototype 对象的 constructor 会被自动设为子类——这个自动修正只发生在 class 语法中,手动操作 prototype 时得自己补。

影响实际开发的细节:

  • new Dog() 创建的实例,Object.getPrototypeOf(new Dog()) === Dog.prototype,而 Object.getPrototypeOf(Dog.prototype) === Animal.prototype

  • 如果子类重写了静态方法,比如 static create(),它不会自动调用父类同名静态方法,必须显式写 super.create()
  • 子类无法直接继承父类的实例属性(如 this.id = Math.random()),只能通过 super() 触发父类构造器执行来获得

真正需要关注的不是“怎么写类”,而是“对象创建时发生了什么”

JavaScript 面向对象的核心从来不是语法,而是三件事:对象如何关联原型、属性查找如何沿链进行、方法调用时 this 如何绑定。类语法掩盖了这些过程,反而容易让人忽略 Object.create(null)Object.setPrototypeOf()Reflect.construct() 这些底层机制的存在价值。

比如你遇到以下情况,就得跳出 class 思维:

  • 需要创建一个无原型的对象(避免继承 Object.prototype 方法)
  • 运行时动态改变某个实例的原型(__proto__ 已废弃,该用 Object.setPrototypeOf()
  • 想让构造函数返回非默认对象(比如缓存已有实例),这时 class 语法完全不支持,必须退回普通函数

复杂点不在语法多难记,而在你是否清楚每个 newextendssuper 背后触发了哪些原型操作。

免责声明:转载请注明出处:http://m.jing-feng.com.cn/news/723505.html

扫一扫高效沟通

多一份参考总有益处

免费领取网站策划SEO优化策划方案

请填写下方表单,我们会尽快与您联系
感谢您的咨询,我们会尽快给您回复!