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

JavaScript中prototype与constructor疑问:代码输出为何两次都是A?

为什么JavaScript原型继承中constructor属性指向不符合预期?

先看这段代码:

function A(){} 
function B(){} 
function C(){} 
B.prototype = new A(); 
console.log(B.prototype.constructor); 
C.prototype = new B(); 
console.log(C.prototype.constructor); 

实际运行后的输出是:

[Function: A]
[Function: A]

但你预期的输出是:

[Function: A]
[Function: B]

这完全是原型继承里一个容易踩的小坑,咱们一步步说清楚:

  • 当你执行 B.prototype = new A() 时,B.prototype 被替换成了A的实例对象。而这个实例的constructor属性是从A.prototype继承来的——默认情况下,A.prototype.constructor就是构造函数A本身。因为你没手动修改B.prototype.constructor,所以它自然指向A。

  • 到了C.prototype = new B(),C.prototype变成了B的实例。但B的实例的constructor属性是沿着原型链找的:B的原型已经是A的实例,所以B实例会顺着原型链找到A.prototype.constructor,也就是A。所以第二次输出还是A。

简单说就是:当你替换构造函数的prototype对象时,新的prototype(是另一个构造函数的实例)不会自动把constructor指向当前构造函数,它会保留原型链上层的constructor指向。

如果要得到你预期的结果,只需要在替换prototype后手动修正constructor指向:

function A(){} 
function B(){} 
function C(){} 

B.prototype = new A();
B.prototype.constructor = B; // 手动修正constructor指向
console.log(B.prototype.constructor); // 此时输出[Function: B]

C.prototype = new B();
C.prototype.constructor = C; // 同样修正
console.log(C.prototype.constructor); // 输出[Function: C]

另外补充个小知识点:现在更推荐用Object.create()来实现原型继承,这样可以避免调用父构造函数带来的不必要副作用,同样记得修正constructor:

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:33:04