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

ES6类构造函数与函数原型构造函数的区别及一致性疑问

ES6类构造函数 vs 函数式构造函数:异同详解

好问题!这俩确实容易让人混淆,我来给你拆解清楚它们的核心异同点~

先看你提到的两种场景

1. 函数式构造函数的情况

你写的这个函数式构造函数:

const Cat = function (name) { this.name = name; };
  • Cat本身就是构造函数,它的原型Cat.prototype默认自带一个constructor属性,指向Cat自己。
  • 如果你直接替换原型:Cat.prototype = {},新的原型对象里就没有constructor了,但new Cat('Mimi')依然能正常运行——这是因为JS创建实例的核心逻辑不依赖原型上的constructor属性,而是靠new操作符后面的那个函数来初始化对象。原型上的constructor更多是个“标识”,用来告诉开发者这个实例是由哪个构造函数生成的,不是实例创建的必要条件。

2. ES6类的情况

再看类的写法:

class Dog {
  constructor(name) { this.name = name; }
}
  • 类本质上是函数的语法糖,Dog本身就是构造函数,Dog.prototype.constructor同样默认指向Dog。
  • 如果你同样替换原型:Dog.prototype = {},原型上的constructor也会丢失,但new Dog('旺财')照样能工作,原因和函数式的情况一样——new操作符认的是你调用的那个构造函数,不是原型上的标记。

核心异同点对比

相同点

  • 本质逻辑一致:不管是类还是函数式构造函数,用new调用时,都会创建新对象、绑定this、执行构造逻辑、把实例的__proto__指向构造函数的prototype。
  • 原型默认都有constructor:两者的prototype对象初始状态下,都包含一个指向自身的constructor属性。

不同点

  • 调用限制:类的构造函数必须用new调用,直接执行Dog()会报错;而普通函数可以直接调用,此时this在非严格模式下指向全局对象,严格模式下是undefined。
  • 枚举性:类的constructor方法是不可枚举的(用Object.keys(Dog.prototype)看不到它);而普通函数原型上的constructor是可枚举的(Object.keys(Cat.prototype)能看到)。
  • 方法定义规范:类内部的所有方法(包括constructor)都会被定义在prototype上,且默认不可枚举;而普通函数如果手动往prototype加方法,默认是可枚举的(除非用Object.defineProperty手动设置不可枚举)。
  • 语法糖封装:类自带extends继承、静态方法(static关键字)等语法,这些在函数式构造函数里需要手动模拟(比如用Object.create实现继承),类帮你封装了这些底层逻辑,更简洁规范。

补充:丢失的constructor怎么恢复?

不管是函数还是类,如果你替换了原型后想恢复constructor标识,只需要手动添加即可:

// 函数式的情况
Cat.prototype = {
  constructor: Cat, // 手动指向Cat
  meow() { console.log('Meow!'); }
};

// 类的情况
Dog.prototype = {
  constructor: Dog, // 手动指向Dog
  bark() { console.log('Woof!'); }
};

这样一来,实例的constructor属性就会正确指向对应的构造函数了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 10:04:03