constructor属性单向存在于构造函数的prototype上,用于溯源而非绑定,手动重写prototype会丢失该属性,需显式补回,且不可靠,应优先使用instanceof或Object.prototype.toString.call()做类型判断。

JS 中原型对象上的 constructor 属性本身并不“双向关联”,它只是单向指向构造函数——准确说,是 构造函数的 prototype 对象上有一个 constructor 属性,值为该构造函数本身。所谓“双向”,其实是开发者通过这个属性,在实例、原型、构造函数三者之间建立可追溯的逻辑链,而非语言层面的自动双向绑定。
constructor 的真实归属位置
它不在实例上,也不在构造函数本体上,而只存在于 构造函数的 prototype 对象中:
-
Person.prototype.constructor === Person✅(默认成立) -
person1.constructor === Person✅(因为person1.__proto__ === Person.prototype,查找到原型上的constructor) -
Person.constructor === Function✅(Person是函数,由Function构造) -
Person.prototype.constructor === Person✅(关键起点)
手动修改 prototype 后 constructor 会丢失
当你用字面量方式重写原型(比如 Star.prototype = { sing() {} }),新对象没有 constructor 属性,自然不会指向原构造函数:
Star.prototype = { sing() {} };-
new Star().__proto__.constructor === Object❌(不是Star) - 解决办法:显式补回
constructor:Star.prototype = { constructor: Star, sing() {} };
constructor 的实际用途是“溯源”,不是“绑定”
它不参与实例创建过程,也不影响继承行为,主要用来判断对象由谁构造:
[].constructor === Array{}.constructor === Object/a/.constructor === RegExp- 自定义类中可用于类型识别:
obj.constructor.name === 'MyClass'
不要依赖 constructor 做类型校验
它容易被覆盖或篡改,可靠性低:
-
Person.prototype.constructor = null;→ 实例的constructor就会沿原型链继续向上找,变成Object - 更健壮的方式是用
instanceof或Object.prototype.toString.call(obj)











