constructor 属性默认指向构造函数但不自动维护,重写 prototype 会使其指向 object 或丢失,需手动设回并推荐用 object.defineproperty 确保不可枚举;class 语法则自动维护。

JavaScript 中 constructor 属性默认指向创建该实例的构造函数,但这个指向**不是自动维护的**——它依赖于原型对象(prototype)上的 constructor 是否正确设置。一旦你重写构造函数的 prototype(比如赋值为一个新对象),就很可能丢失这个指向,需要手动修复。
为什么 constructor 会“断掉”?
当你直接给构造函数的 prototype 赋一个新对象(如 Person.prototype = { ... }),这个新对象没有 constructor 属性,或者它的 constructor 指向 Object(因为字面量对象的原型是 Object.prototype)。此时实例的 constructor 就不再指向原构造函数。
如何手动指回构造函数?
在重写 prototype 后,显式把 constructor 属性设回去即可:
- 用对象字面量重写时,在对象里加上
constructor: Person - 用
Object.assign或展开语法时,记得补上constructor - 如果用
Object.create()创建原型,可先设置再赋值
例如:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
function Person(name) {
this.name = name;
}
// ❌ 错误:直接赋值会丢失 constructor
Person.prototype = {
sayHello() { console.log('Hi'); }
};
console.log(new Person().constructor); // Object,不是 Person
// ✅ 正确:显式指定 constructor
Person.prototype = {
constructor: Person, // ← 关键一行
sayHello() { console.log('Hi'); }
};
console.log(new Person().constructor === Person); // true
更安全的写法:用 Object.defineProperty
为了确保 constructor 不被意外修改(比如被 for...in 遍历到或被重写),推荐用 Object.defineProperty 设置,并设为不可枚举:
Person.prototype = {
sayHello() { console.log('Hi'); }
};
Object.defineProperty(Person.prototype, 'constructor', {
value: Person,
enumerable: false, // for...in 不会遍历到
writable: true,
configurable: true
});
ES6 类中 constructor 是自动维护的
使用 class 语法时,引擎会自动在原型上设置正确的 constructor,无需手动干预:
class Animal {
constructor(name) {
this.name = name;
}
speak() { console.log('...'); }
}
console.log(Animal.prototype.constructor === Animal); // true
// 即使扩展原型,只要不覆盖整个 prototype,一般不会出问题
但如果用 Animal.prototype = {...} 彻底替换,同样需要手动恢复 constructor。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










