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

关于new与Object.create的原型继承差异:为何cat无法调用eat方法?

关于JavaScript构造函数、原型与new关键字的疑问解答

首先得纠正你一个认知:new Animal()并不完全等同于Object.create(Animal.prototype),后者只是new操作的第一步,完整的new过程还包含调用构造函数这关键一步,这就是问题的核心。

先看const dog = new Animal()的执行逻辑

当你用new调用构造函数时,JS会做三件事:

  1. 创建一个空对象,让这个对象的[[Prototype]](原型)指向Animal.prototype
  2. 调用Animal构造函数,把构造函数里的this绑定到这个新创建的空对象上
  3. 如果构造函数没有返回自定义对象,就把这个新对象作为返回值(也就是这里的dog)

所以Animal构造函数里的this.eat = function() {...},其实是直接给dog这个对象本身添加了一个自有属性eat,根本不是从原型继承来的——你调用dog.eat()时,找的是它自己身上的方法,自然能正常执行。

再看两种cat的情况

1. const cat = Object.create(Animal)

这里你把Animal这个构造函数本身当作了原型,所以cat的原型链是:cat → Animal函数 → Function.prototype → Object.prototype。整个链条里都没有eat方法,所以调用cat.eat()自然会报错“不是函数”。

2. const cat = Object.create(Animal.prototype)

这种方式确实创建了一个原型指向Animal.prototype的对象,但它没有触发Animal构造函数的执行。你的eat方法是写在构造函数内部、通过this赋值给实例的,而Animal.prototype本身并没有eat这个属性——所以cat的原型链里找不到eat,调用时同样报错。

为什么把eat放到Animal.prototype上就可以?

当你把eat直接赋值给Animal.prototype.eat时,Animal.prototype上就有了这个方法。此时用Object.create(Animal.prototype)创建的cat,它的原型指向Animal.prototype,当调用cat.eat()时,JS会沿着原型链找,在Animal.prototype上找到eat方法,自然就能正常执行了。

总结一下:

  • 构造函数内部通过this添加的属性/方法,是实例的自有属性,只有在调用构造函数时才会被添加到实例上
  • Object.create()只是创建一个指定原型的空对象,不会自动调用构造函数
  • new关键字的核心是:创建原型关联的对象 + 调用构造函数初始化实例属性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 13:24:49