首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【前端】深入对比 JavaScript 中的工厂模式与自定义构造函数模式

【前端】深入对比 JavaScript 中的工厂模式与自定义构造函数模式

作者头像
CSDN-Z
发布2025-06-02 10:15:28
发布2025-06-02 10:15:28
16900
代码可运行
举报
文章被收录于专栏:AIGCAIGC
运行总次数:0
代码可运行

💯前言

  • JavaScript 编程领域,对象的创建是一个至关重要的需求,不同的场景和需求决定了采用何种创建对象的方式。在这其中,工厂模式自定义构造函数模式是两种经典的对象创建方法。 这两种模式在结构实现细节原型链的关联性内存管理等方面各具特点。本文旨在对比分析工厂模式自定义构造函数模式概念实现方式适用场景以及各自的优劣之处,以便开发者能够根据具体需求选择最佳的对象创建策略。 JavaScript

💯工厂模式(Factory Pattern)

1.1 工厂模式概述

工厂模式是一种设计模式,通过定义一个函数来创建并返回一个新对象。它的设计灵感来源于现实生活中的“工厂”:工厂生产各种产品,而工厂函数则生产具有类似结构的对象。

JavaScript 中,工厂模式通过一个函数封装对象的创建逻辑,并返回新对象。工厂模式的核心在于封装对象的创建细节,使得对象的创建过程对于使用者透明化,并且能够根据不同需求灵活生成所需的对象。

工厂模式提供了一种简单且灵活的对象创建方式,特别适用于那些结构相似但无需复杂继承关系的对象。由于工厂模式无需使用new关键字,也没有构造函数原型链的复杂性,它对于开发者来说是非常直观的。

同时,它能够根据传入的参数自由调整对象的结构,因而在构建相似对象但又需要某些特殊定制的场景中尤为适用。


1.2 工厂模式的实现

以下是一个典型的工厂函数的实现示例:

代码语言:javascript
代码运行次数:0
运行
复制
function createStudent(name, age, sex) {
    var obj = new Object(); //new 构造函数();
    obj.name = name;
    obj.age = age;
    obj.sex = sex;
    obj.speak = function () {
        console.log('我要学习,学习使我快乐,学习让我成长!');
    }
    return obj;
}
var stu1 = createStudent('小明', 99, 'Man');

console.log(stu1 instanceof createStudent); // false
console.log(stu1 instanceof Object);        // true

在该示例中,createStudent 函数是一个典型的工厂函数。它接收参数 nameagesex,然后创建并返回一个具有这些属性和 speak 方法的对象。通过调用 createStudent('小明', 99, 'Man'),即可得到一个名为“小明”的学生对象。这种实现方式尤其适合于创建多个类似对象的场景,从而避免重复编写对象创建代码,提高开发效率和代码可读性。


1.3 工厂模式的优缺点


优点

  1. 代码简洁且易用:工厂函数的调用方式非常直观,开发者无需关心new关键字或对象实例化的内部机制,直接调用函数即可创建对象。
  2. 屏蔽创建细节,增强封装性:工厂函数将对象创建的具体细节封装在函数内部,外部调用者无需知悉对象创建的细节,只需关注最终生成的对象。这种封装性有助于代码的模块化,使得代码更具可维护性
  3. 灵活的对象结构:工厂模式允许动态地为对象添加属性和方法,开发者可以根据不同需求对对象结构进行调整,从而灵活应对业务变化

缺点
  1. 缺乏类型识别:由于工厂函数返回的对象没有与其原型关联,不能通过 instanceof 运算符来判断对象的类型。例如,stu1 instanceof createStudent 返回 false,因为 createStudent 并不是一个构造函数,也没有原型链上的关系。
  2. 方法无法共享:每次调用工厂函数都会创建新的对象及方法实例,导致每个对象都持有自己的方法副本。这种实现方式在需要创建大量对象且对象方法较多的情况下,会造成显著的内存开销,增加系统负担。


💯自定义构造函数模式(Constructor Pattern)


2.1 自定义构造函数概述

自定义构造函数是一种实现面向对象编程的方式,其理念类似于传统面向对象编程语言中的类(Class)。尽管 JavaScript 在 ES6 之前没有“类”的概念,但可以通过函数模拟类的行为,并结合 new 关键字来创建对象。这种构造函数模式是一种以“函数”作为类定义,通过 new 运算符来实例化的对象创建方式。

当使用 new 调用构造函数时,JavaScript 引擎会自动执行以下步骤:

  1. 创建一个新的空对象;
  2. 将该对象的 __proto__ 属性指向构造函数的 prototype 属性,建立原型链关联;
  3. 将构造函数内部的 this 绑定到新创建的对象上,并执行构造函数代码;
  4. 返回新创建的对象实例。

构造函数模式不仅可以通过原型链实现方法共享,还为开发者提供了创建结构化对象的强大工具。通过构造函数,开发者能够系统性地组织代码,使其更具可扩展性和可复用性。


2.2 构造函数模式的实现

以下是自定义构造函数的实现示例:

代码语言:javascript
代码运行次数:0
运行
复制
function Student(name, age, sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.speak = function () {
        console.log('我要学习, 学习使我快乐, 学习让我成长! 我叫 ' + this.name);
    };
}

var stu3 = new Student('张三', 18, 'Man');

console.log(stu3 instanceof Student); // true
console.log(stu3 instanceof Object);  // true

在上述示例中,Student 函数充当了构造函数的角色。通过使用 new Student('张三', 18, 'Man'),可以创建一个具有 nameagesexspeak 方法的新对象 stu3。每次调用 new 创建新的实例时,构造函数中的代码都会被执行。

为了进一步优化内存使用,建议将方法定义在构造函数的 prototype 属性上,从而实现方法的共享:

代码语言:javascript
代码运行次数:0
运行
复制
Student.prototype.speak = function () {
    console.log('我要学习, 学习使我快乐, 学习让我成长! 我的名字是' + this.name);
}

将方法定义在 prototype 上使得所有通过构造函数创建的对象实例共享这些方法。这不仅节约了内存资源,还使得代码在处理大批量对象时更加高效。


2.3 构造函数模式的优缺点

优点
  1. 支持类型识别:通过构造函数创建的对象可以通过 instanceof 运算符进行类型判断。例如,stu3 instanceof Student 返回 true,这对于需要类型检查的场景非常有用。
  2. 方法共享,节省内存:通过将方法定义在 prototype 上,所有对象实例可以共享这些方法,从而显著减少内存占用,尤其是在需要创建大量实例的场景中,这种共享机制可以提升性能。
  3. 易于扩展:构造函数和原型链的结合使得对象行为的扩展非常容易。开发者可以在 prototype 上动态地添加新的方法或属性,无需修改原始构造函数。

缺点
  1. 语法相对复杂:与工厂模式相比,构造函数模式需要开发者理解 new 关键字的机制及其对 this 的影响,语法相对复杂。如果开发者忘记使用 newthis 会默认指向全局对象(在严格模式下为 undefined),从而产生隐蔽且难以排查的错误。
  2. 调用误用风险:由于需要手动使用 new 关键字,错误地调用构造函数(即直接调用而不使用 new)可能导致逻辑错误。因此,构造函数模式对开发者的要求较高,需要非常熟悉 JavaScript 的执行上下文和 this 的绑定规则。


💯工厂模式与构造函数模式的对比


3.1 对象创建的方式

  • 工厂模式:通过调用一个普通函数创建对象,函数内部手动创建对象并返回。
  • 构造函数模式:通过 new 关键字调用构造函数,构造函数使用 this 引用新创建的对象。


3.2 类型判断

  • 工厂模式:无法通过 instanceof 判断对象的类型,因为工厂函数与创建的对象之间没有原型链关联。
  • 构造函数模式:可以通过 instanceof 判断对象是否属于某个构造函数。


3.3 方法的共享性

  • 工厂模式:每次调用工厂函数都会创建新的对象和方法副本,无法实现方法共享,导致内存浪费。
  • 构造函数模式:可以通过 prototype 实现方法共享,节省内存。


3.4 使用场景

  • 工厂模式:适用于创建简单对象或无需严格类型判断的场景,具有较高的灵活性,代码简洁。非常适合快速原型开发。
  • 构造函数模式:适用于需要创建复杂对象结构,支持原型链继承,且需要类型识别的场景。适合复杂应用的构建,尤其是当开发者需要为对象添加共享行为时。


3.5 直观对比表格

比较点

工厂模式

构造函数模式

对象创建方式

调用普通函数

使用 new 调用构造函数

类型判断

instanceof 无法判断类型

可以使用 instanceof 判断类型

方法共享性

无法共享方法,每次创建新方法实例

可通过 prototype 实现方法共享

代码简洁性

代码更为简洁

使用 new 语法相对复杂

错误风险

无需 new,风险较小

忘记 new 时会导致错误


💯结合 ES6 类的新方式

ES6 引入了 class 关键字,使得对象的构造与面向对象编程更为契合。class 的语法是一种对构造函数的语法糖,使代码更直观,易于理解。

代码语言:javascript
代码运行次数:0
运行
复制
class Student {
    constructor(name, age, sex) {
        this.name = name;
        this.age = age;
        this.sex = sex;
    }
    speak() {
        console.log('我要学习, 学习使我快乐, 学习让我成长! 我的名字是' + this.name);
    }
}

let stu4 = new Student('李四', 20, 'Man');

在这个示例中,class 定义了一个 Student 类,constructor 方法用于初始化对象,而 speak 方法是定义在 prototype 上的共享方法。这种语法让代码的组织更加符合面向对象编程的直觉。使用 class 还可以更好地控制封装性和继承性,降低开发者在使用构造函数时可能遇到的误用风险。


💯小结

在 JavaScript 中,工厂模式与构造函数模式是两种经典的对象创建方法。如何选择取决于具体需求:

  • 工厂模式 提供了一种简单快捷的对象创建方式,特别适合快速开发和无需类型判断的场景。
  • 构造函数模式 则适合那些需要类型识别和方法共享的场景,通过 prototype 提供共享方法以提高内存利用效率。
  • ES6 的 class 引入后,使得对象构造变得更加符合传统面向对象编程的习惯,结合了构造函数的功能与更加简洁的语法。

理解这些模式的差异是掌握 JavaScript 面向对象编程的基础,开发者在实际开发中应根据具体需求选择合适的模式,以提高代码的可维护性可扩展性效率。在简单场景中,工厂模式可能是最简单的解决方案,而在更复杂的应用中,构造函数的方式则提供了更强大的功能支持。不同模式的灵活运用可以显著提升代码质量,使得代码更加易于维护和扩展

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 💯前言
  • 💯工厂模式(Factory Pattern)
    • 1.1 工厂模式概述
    • 1.2 工厂模式的实现
    • 1.3 工厂模式的优缺点
      • 优点
      • 缺点
  • 💯自定义构造函数模式(Constructor Pattern)
    • 2.1 自定义构造函数概述
    • 2.2 构造函数模式的实现
    • 2.3 构造函数模式的优缺点
      • 优点
      • 缺点
  • 💯工厂模式与构造函数模式的对比
    • 3.1 对象创建的方式
    • 3.2 类型判断
    • 3.3 方法的共享性
    • 3.4 使用场景
    • 3.5 直观对比表格
  • 💯结合 ES6 类的新方式
  • 💯小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档