正确设置子类 constructor 指向自身而非父类,关键在于使用 object.create 设置原型后需手动修复:dog.prototype.constructor = dog 或 object.defineproperty(dog.prototype, 'constructor', { value: dog, enumerable: false });es6 class 自动维护该指向。

在 JavaScript 继承中,正确设置构造函数的指向,关键在于让子类实例的 constructor 属性准确指向子类自身,而不是父类。这直接影响 instanceof 判断、原型链调试和代码可维护性。
为什么 constructor 会出错?
使用 Object.create(Parent.prototype) 设置子类原型时,子类原型对象的 constructor 会沿用父类的构造函数,因为 Object.create 创建的对象其 constructor 默认指向原型链上的第一个有效构造器(即父类)。
例如:
function Animal() {}
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
console.log(Dog.prototype.constructor === Animal); // true → 错误!应为 Dog
手动修复 constructor 指向
在设置完原型后,显式将子类原型的 constructor 指回子类函数本身:
- 直接赋值:
Dog.prototype.constructor = Dog; - 推荐写法(避免属性被意外遍历):
Object.defineProperty(Dog.prototype, 'constructor', { value: Dog, enumerable: false, writable: true, configurable: true });
ES6 class 中自动处理
使用 class 语法时,JavaScript 引擎会自动维护正确的 constructor 指向:
class Animal {}
class Dog extends Animal {}
console.log(Dog.prototype.constructor === Dog); // true
console.log(new Dog() instanceof Dog); // true
即使继承了父类,子类的 constructor 也始终指向自身,无需手动干预。
搭配 call 实现属性继承时仍需关注 constructor
仅在子类构造函数中用 Parent.call(this, ...) 只能继承实例属性,不涉及原型链或 constructor。若同时修改了原型(如设置 Child.prototype = Object.create(Parent.prototype)),就必须手动修复 constructor,否则会出现:
-
new Child() instanceof Child为true(因 new 绑定正常),但 -
new Child().constructor === Child为false(实际指向 Parent)
这会让依赖 constructor 的序列化、工厂模式或类型检查逻辑出错。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











