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

构造函数与类的区别:创建对象的两种方式技术差异咨询

构造函数 vs ES6类:核心差异解析

嘿,这个问题问得特别到位——很多刚摸透JS原型链的开发者都会纠结构造函数和ES6类的区别,我来给你拆解清楚两者的核心差异,结合你贴的代码例子来说:

1. 语法本质与结构清晰度

ES6的class其实是原型继承的语法糖,它并没有改变JS基于原型的本质,但写法更贴近传统面向对象语言(比如Java、Python),结构更规整:

  • 你的类示例里,构造逻辑被单独放在constructor方法中,而doSomething这类实例方法直接写在类体里,一眼就能区分初始化逻辑和实例行为。
  • 而ES5构造函数的写法,所有逻辑(包括方法定义)都挤在同一个函数里,像你写的doSomething是直接挂载在this上的,每个实例都会生成一个新的函数副本,既占内存又不直观。

2. 方法的挂载位置(内存效率差异)

这是两者最关键的实用差异:

  • 构造函数版本:你代码里的this.doSomething = function (){},意味着每创建一个Thing实例,都会新建一个独立的doSomething函数。如果创建1000个实例,就有1000个一模一样的函数,非常浪费内存。如果想让方法共享,你得手动把方法挂到原型上:
    function Thing(name) {
      this.name = name;
      alert("A new thing was created.");
    }
    // 手动挂载到原型,所有实例共享
    Thing.prototype.doSomething = function() {};
    
  • 类版本:类体里定义的doSomething()默认就挂载在Thing.prototype上,所有实例共享同一个函数,内存效率更高,不用手动处理原型。

3. 调用限制与安全性

  • 类的constructor必须用new调用:如果直接写Thing(),JS会直接抛出错误,避免了忘记加new导致的意外问题。
  • 构造函数的风险:如果忘了加new调用Thing(),非严格模式下this会绑定到全局对象(比如浏览器里的window),导致name变成全局变量;严格模式下虽然会报错,但不如类的限制直接。

4. 继承的便捷性

如果后续需要实现继承,两者的写法复杂度天差地别:

  • 类继承:用extends和super就能轻松实现,语法简洁不易出错:
    class SubThing extends Thing {
      constructor(name, type) {
        super(name); // 调用父类构造函数
        this.type = type;
      }
    }
    
  • 构造函数继承:需要手动拼接原型链,还要手动调用父类构造函数,步骤繁琐容易踩坑:
    function SubThing(name, type) {
      Thing.call(this, name); // 调用父类构造函数绑定this
      this.type = type;
    }
    // 继承原型方法
    SubThing.prototype = Object.create(Thing.prototype);
    // 修正constructor指向
    SubThing.prototype.constructor = SubThing;
    

5. 其他细节差异

  • 静态方法:类可以用static关键字直接定义静态方法(比如static createThing() { return new Thing(); }),直接通过Thing.createThing()调用;构造函数的静态方法需要手动挂在构造函数本身上(Thing.createThing = function() {}),效果一致但类的写法更规范。
  • Getter/Setter:类支持直接定义get和set访问器,比如:
    class Thing {
      constructor(name) {
        this._name = name;
      }
      get name() { return this._name; }
      set name(val) { this._name = val; }
    }
    
    构造函数要实现同样的效果,得用Object.defineProperty,写法繁琐很多。

总结一下:ES6类并没有创造新的JS特性,只是让原型继承的写法更简洁、更符合传统OOP的直觉,同时减少了构造函数写法容易出现的错误。如果你的项目支持ES6+,优先用类会更省心;如果要兼容老环境,就用构造函数+原型的写法。

内容的提问来源于stack exchange,提问作者D. Pardal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:48:55