JavaScript中可通过实例的constructor属性访问构造函数,但该属性可被修改且在继承、Object.create(null)等场景下不可靠;应优先使用instanceof、Object.prototype.toString.call()等更健壮的类型判断方法。

JavaScript中可以通过实例的constructor属性直接访问其构造函数,但需注意它不是绝对可靠——该属性可被修改,且在继承链或使用Object.create(null)等场景下可能失效。
constructor属性的基本用法
每个实例对象(除null和undefined外)默认拥有constructor属性,指向创建它的构造函数:
-
const arr = [];→arr.constructor === Array为 true -
const date = new Date();→date.constructor === Date为 true -
function Person() {},const p = new Person();→p.constructor === Person为 true
constructor属性可能被覆盖或丢失
该属性存在于实例的原型上,不是自有属性,因此容易被意外修改或遮蔽:
- 如果原型被整体替换(如
Child.prototype = Parent.prototype),constructor会指向Parent而非Child - 若手动设置
Child.prototype.constructor = Child被遗漏,反向获取就会出错 - 用
Object.create(null)创建的对象没有原型,自然没有constructor属性 - 箭头函数、字面量对象(
{})、Object.create({})等没有显式构造函数,constructor指向Object,但不具区分性
更健壮的替代方案
当需要高可靠性时,应结合其他机制:
立即学习“Java免费学习笔记(深入)”;
- 用
Object.getPrototypeOf(obj).constructor显式读取原型上的constructor,比直接访问obj.constructor稍安全(避免自有属性遮蔽) - 配合
instanceof或Object.prototype.toString.call(obj)判断类型,例如:Object.prototype.toString.call([]) === '[object Array]' - ES6起可用
obj.constructor?.name获取函数名,但依然依赖constructor存在且未被篡改
实际开发中的建议
仅在可控、简单场景下依赖constructor;涉及继承、框架封装或动态原型操作时,优先使用instanceof、Symbol.toStringTag或自定义类型标识(如obj.$$type = 'MyClass')。


















