You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

对象constructor属性疑问:为何new Rabbit()实例的constructor指向Animal?

为什么r.constructor指向Animal而不是Rabbit?

嘿,这个问题绝对是JS原型链入门时最容易踩的坑之一,我来给你拆解明白~

先看你贴的核心代码:

function Animal(){ this.name = 'Animal' }
var animal1 = new Animal();
function Rabbit(){ this.canEat = true; }
Rabbit.prototype = new Animal(); // 这行是关键转折点
var r = new Rabbit();
console.log(r.constructor) // 输出Animal

问题出在哪?

默认情况下,每个函数的prototype对象里都自带一个constructor属性,这个属性默认指向函数本身。比如一开始Rabbit.prototype.constructor是指向Rabbit的。

但当你执行Rabbit.prototype = new Animal()时,你把Rabbit原来的原型对象整个替换成了Animal的实例。而这个Animal实例的原型链是:animal实例 -> Animal.prototype,Animal.prototype.constructor默认是Animal。

当你访问r.constructor时,JS会顺着原型链往上找:

  1. 先看r自身有没有constructor?没有,因为你没在Rabbit里定义它。
  2. 然后找r.__proto__(也就是Rabbit.prototype,现在是Animal的实例),这个实例自身也没有constructor。
  3. 继续往上找Animal.prototype,这里的constructor指向Animal,所以最终返回的就是Animal。

为什么赋值prototype前调用Rabbit就正常?

如果你先创建r,再替换Rabbit.prototype:

var r = new Rabbit(); // 先创建实例
Rabbit.prototype = new Animal(); // 再替换原型
console.log(r.constructor) // 输出Rabbit

这是因为实例的原型指向是在new的时候就固定下来的。r的__proto__指向的是Rabbit原来的原型对象(那个自带constructor: Rabbit的对象),之后你修改Rabbit.prototype并不会影响已经创建好的r的原型链。

怎么解决这个问题?

很简单,替换完Rabbit.prototype之后,手动把constructor指回Rabbit就行:

function Animal(){ this.name = 'Animal' }
function Rabbit(){ this.canEat = true; }
Rabbit.prototype = new Animal();
Rabbit.prototype.constructor = Rabbit; // 手动修正constructor指向
var r = new Rabbit();
console.log(r.constructor) // 现在输出Rabbit啦!

这样r顺着原型链找constructor时,会先找到Rabbit.prototype上的constructor,也就是Rabbit,就符合你的预期了。

内容的提问来源于stack exchange,提问作者Mayank

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:53:12