JavaScript中class语法与手动操作prototype存在本质差异:实例属性挂载在this上、独立不共享;方法默认不可枚举地挂载到prototype;静态成员直接赋值给构造函数;constructor自动维护且不可配置。

JavaScript 中 class 语法里定义的属性,和手动往 prototype 上挂方法,底层行为并不相同——不是“写法不同但效果一样”,而是**赋值目标、时机、可枚举性、内存位置**都存在明确差异。
实例属性直接挂在 this 上,不进原型链
在 class 中写 public 实例字段(如 name = "Alice"),等效于在 constructor 里执行 this.name = "Alice"。这个属性属于实例本身,每次 new 都会独立创建一份,不会共享,也不经过原型查找。
- 它出现在实例对象自身的属性中(
Object.keys(instance)能看到) - 修改它不影响其他实例,也不会触发原型链访问
- 这类字段不参与继承,子类实例也只拥有自己那一份
实例方法默认挂到 prototype,且不可枚举
class 内定义的普通方法(如 sayHello() { ... })会被自动添加到 ClassName.prototype 上,但引擎会用 Object.defineProperty 设置 enumerable: false。
- 所有实例通过
__proto__共享同一个函数引用,节省内存 -
for...in或Object.keys()不会遍历到它,而手动挂到 prototype 的方法默认是可枚举的 - 本质等价于:
Object.defineProperty(ClassName.prototype, 'sayHello', { value: function() {...}, enumerable: false })
静态成员直接挂在构造函数上,与 prototype 无关
static 方法或字段(如 static version = '1.0')被赋值给 class 本身,即构造函数对象,而不是它的 prototype。
立即学习“Java免费学习笔记(深入)”;
-
MyClass.version可直接访问,new MyClass().version是 undefined - 它和
MyClass.prototype没有继承关系,也不影响实例的__proto__链 - 静态继承(
Child.__proto__ === Parent)由extends自动建立,传统原型写法无法原生支持
constructor 指向自动维护,无需手动修复
class 声明后,ClassName.prototype.constructor 会自动指向该 class,且不可枚举、不可配置。
- 你不需要像传统写法那样写
Child.prototype.constructor = Child - 如果手动改写
prototype(比如用Object.create(Parent.prototype)),constructor 就断了,必须重设 - class 的 prototype 是“受控对象”,引擎确保其初始结构完整


















