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

原型链中‘new person()’与‘person.prototype’的区别及继承疑问

关于JS原型继承的两个核心问题解答

嘿,这个问题问到点子上了,原型继承里这两个细节很容易搞混,我来给你拆解清楚:

1. 直接用person1.prototype = person.prototype继承父类原型属性是否正确?

答案是:绝对不推荐,甚至可以说是错误的做法。

原因很简单:JavaScript里对象是引用类型,当你把person.prototype直接赋值给person1.prototype时,二者指向的是同一个内存地址的对象。这意味着后续你给子类原型添加的任何方法(比如你的代码里的tellMyAge),都会直接修改父类的原型对象。

举个直观的例子,如果你这么写:

person1.prototype = person.prototype;
person1.prototype.tellMyAge = function () { console.log(this.age); }

// 现在父类的实例也能调用子类的方法了!
const parentInst = new person("Bob");
parentInst.tellMyAge(); // 输出undefined(因为父类实例没有age属性)

这完全违背了继承的初衷——我们希望子类拥有自己独立的原型,不会影响父类的原型和实例。

2. 原型链中new person()与person.prototype的区别

这两者本质是完全不同的对象,放在原型链里的作用也天差地别:

① person.prototype:父类的原型对象本身

  • 它是一个普通对象,是所有父类实例的__proto__指向的目标。
  • 如果把它赋值给子类原型,子类和父类会共享同一个原型对象,就会出现上面说的“子类修改原型影响父类”的问题。
  • 此时子类实例的原型链是:子类实例 -> person.prototype -> Object.prototype

② new person():父类的一个实例对象

  • 当你调用new person()时,会创建一个新对象,这个新对象的__proto__会指向person.prototype,同时会执行父类构造函数里的代码(给实例添加属性,比如你的代码里的this.myName)。
  • 把这个实例赋值给子类原型后,子类原型是一个独立的对象(父类实例),子类添加新方法只会修改这个独立对象,不会影响父类的原型。
  • 此时子类实例的原型链是:子类实例 -> new person()实例 -> person.prototype -> Object.prototype

不过这里要补充一个小细节:用new person()作为子类原型的话,父类构造函数里的实例属性(比如myName)会被继承到子类原型上(值是undefined,因为你调用new person()时没传name参数),这其实是不必要的。所以更优雅的做法是用Object.create(person.prototype)来创建一个以person.prototype为原型的空对象,避免继承这些多余的实例属性:

person1.prototype = Object.create(person.prototype);
// 别忘了把子类原型的constructor指回自己,不然会指向person
person1.prototype.constructor = person1;

回到你的代码,你用new person()的方式是可行的(虽然有小瑕疵),但绝对不能直接赋值person.prototype给子类原型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:02:36