javascript的类是什么_与构造函数有何关联

11次阅读

javaScript的class本质是构造函数与原型链的语法糖,底层仍基于functionprototype机制,其声明生成不可枚举、不可重写的函数对象,且不被提升。

javascript的类是什么_与构造函数有何关联

javascriptclass 本质是语法糖,底层仍基于构造函数和原型链

它不是新增的面向对象机制,而是对已有 function 构造函数 + prototype 模式的封装。写 class 时,js 引擎会自动把它转成等价的构造函数形式。

class 声明会创建一个不可枚举、不可重写、有 constructor 属性的函数

虽然看起来像“类”,但 class Person 实际生成的是一个特殊函数对象,其 typeof 仍是 "function",且该函数默认不可被 new.target 以外的方式调用(直接调用会报 Class constructor Person cannot be invoked without 'new')。

class Person {   constructor(name) {     this.name = name;   } } console.log(typeof Person); // "function" console.log(Person.prototype.constructor === Person); // true console.log(Person.name); // "Person"
  • class 内部方法默认不可枚举(Object.keys(Person.prototype) 不会返回 constructor 或其他方法)
  • class 声明不会被提升(ReferenceError),而 function 声明会被提升
  • class 中的 constructor 必须是函数,且不能是箭头函数或生成器

继承关系完全复用 functionprototype__proto__

extends 关键字只是在背后调用 Object.setPrototypeOf(Sub.prototype, Super.prototype)Object.setPrototypeOf(Sub, Super),和手动设置 Sub.prototype = Object.create(Super.prototype) 效果一致。

class Animal {} class Dog extends Animal {}  // 等价于: function Animal() {} function Dog() {} Object.setPrototypeOf(Dog.prototype, Animal.prototype); Object.setPrototypeOf(Dog, Animal);
  • super()子类 constructor 中必须显式调用,否则无法访问 this —— 这是因为子类构造函数中 this 尚未初始化,而 JS 引擎强制要求由 super() 触发父类初始化逻辑
  • super.xxx 访问父类属性/方法时,this 仍指向当前实例,不是父类实例
  • 静态方法继承也是靠 Object.setPrototypeOf 实现,所以 Dog.eat === Animal.eatfalse,除非显式赋值

实际编码中容易忽略的关键差异点

这些不是“理论区别”,而是上线后可能引发隐性 bug 的地方:

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

  • 类字段(如 name = 'tom')在构造函数执行前就已初始化,且仅对实例生效;而构造函数内赋值(this.name = 'tom')可依赖参数或异步逻辑
  • 类中的方法自动绑定到原型,但类字段声明的箭头函数会绑定到实例,造成内存不共享 —— 和传统构造函数里手写 this.fn = () => {} 行为一致
  • 私有字段(#name)不走原型链,也不能被子类访问,哪怕子类也声明同名私有字段,它们也是完全隔离的
  • Babel 转译 class 时若目标环境不支持 class,会降级为 function + Object.defineProperty 模拟,此时 instanceof 仍可靠,但某些调试工具可能显示为 Function 而非 class

真正要警惕的,不是“该不该用 class”,而是当调试原型链、动态修改方法、或与老旧库混用时,误以为 class 切断了和函数本质的联系。

text=ZqhQzanResources