constructor属性不通过原型链动态查找,而是直接从实例的__proto__上读取;它默认由构造函数自动设置在prototype上,手动重写prototype时需显式恢复,否则指向错误。

构造函数在实例化时,constructor 属性**并不通过原型链动态查找**,而是**直接从实例的 __proto__(即其原型对象)上读取**。这个属性通常就是该原型对象被创建时自动设置的引用,指向当初用来生成它的构造函数。
constructor 属性的来源是原型对象本身
当你用 function Foo() {} 定义构造函数,JavaScript 引擎会自动为 Foo.prototype 添加一个 constructor 属性,值为 Foo 本身:
-
Foo.prototype.constructor === Foo→ true - 实例
const f = new Foo()的f.__proto__就是Foo.prototype - 所以
f.constructor实际等价于f.__proto__.constructor,也就是Foo.prototype.constructor
它不是“沿原型链逐级向上找”,而是单层访问
虽然 f.constructor 看似像属性访问,但它不触发完整的原型链遍历(比如不会去查 Object.prototype 上有没有 constructor)。JS 引擎会:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- 先检查
f自身是否有constructor(一般没有) - 再直接读取
f.__proto__.constructor(仅一层) - 如果该值存在且可枚举(默认是),就返回它;否则继续查
f.__proto__.__proto__.constructor—— 这才是真正的链式查找,但标准行为中constructor通常已在第一层定义
手动修改 prototype 时容易出问题
如果你重写了整个 prototype,却没恢复 constructor,实例的 constructor 就会指向错误的函数:
-
Foo.prototype = { say() {} };→ 此时Foo.prototype.constructor变成Object -
new Foo().constructor === Object→ true(意外!) - 修复方式:
Foo.prototype.constructor = Foo;或用Object.defineProperty显式设置
ES6 class 中 behavior 一致但更隐蔽
class Bar {} 底层仍基于原型,Bar.prototype.constructor 也指向 Bar。你不能在 class 字面量里直接写 constructor 属性,但可以:
- 在 class 内定义
constructor() {}方法(这是必须的,且会成为prototype.constructor) - 或在 class 外补:
Bar.prototype.constructor = Bar;(极少需要)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










