constructor属性指向创建实例的构造函数,但因可被修改或原型重写而不可靠;应优先使用instanceof、Object.prototype.toString.call()或Object.getPrototypeOf()判断类型。

对象的 constructor 属性指向创建该实例的构造函数,这是识别对象“出身”的最直接方式。但它不是万能的,需注意原型链和属性可写性带来的干扰。
constructor 属性的基本用法
每个由构造函数创建的实例,默认在原型上继承一个 constructor 属性,值为该构造函数本身:
function Person(name) {
this.name = name;
}
const p = new Person('Alice');
console.log(p.constructor === Person); // true
内置对象同理:
const arr = [1, 2, 3]; console.log(arr.constructor === Array); // true const date = new Date(); console.log(date.constructor === Date); // true
constructor 可能失真的常见情况
constructor 是原型上的普通属性,可以被修改或覆盖,不能完全信赖:
- 手动改写原型导致丢失:
Person.prototype = { say() {} };—— 此时p.constructor指向Object,不再是Person - 显式赋值覆盖:
Person.prototype.constructor = null;或Person.prototype.constructor = String; - 使用
Object.create(null)创建的对象没有constructor属性
更可靠的替代方案
当需要稳健判断实例类型,优先考虑以下方法:
-
instanceof:检测原型链中是否存在某构造函数的prototypep instanceof Person—— 即使constructor被改,只要原型链未断,结果仍准 -
Object.prototype.toString.call():获取内部 [[Class]] 标签,适合判断内置类型Object.prototype.toString.call([])→"[object Array]"Object.prototype.toString.call(new Date())→"[object Date]" -
Object.getPrototypeOf():直接获取原型对象,再比对constructor(更底层、不易被污染)Object.getPrototypeOf(p) === Person.prototype
修复 constructor 的典型做法
若重写了原型,应手动恢复 constructor:
Person.prototype = {
constructor: Person, // 显式补回
say() { console.log(this.name); }
};
// 或更稳妥地:
Object.defineProperty(Person.prototype, 'constructor', {
value: Person,
enumerable: false,
writable: true,
configurable: true
});










