JavaScript 工厂模式详解:从简单实现到 DOM 扩展应用

作者:流萤

时间:2026-10-26

浏览:173

本文深入解析 JavaScript 中的工厂模式,涵盖简单工厂与静态工厂两种实现方式。通过 Fruit 类与 Object 构造函数的示例,阐明如何通过函数调用替代 new 操作符以降低耦合。文章进一步展示如何利用工厂模式封装 DOM 节点,动态添加自定义方法如 say 和 createForm,实现类似 jQuery 的链式调用体验,并提供完整的 HTML 与 JS 代码示例。

文章目录

工厂模式概述与简单实现

工厂模式属于对象创建型设计模式之一,通常实现在类或其静态方法中。虽然使用 new 操作符是构造对象的常见方式,但它直接针对具体实现编程,容易引发类之间的紧密耦合,导致代码脆弱且缺乏弹性。在逻辑复杂的项目中,推荐采用面向接口编程的策略,而工厂模式正是实现这一目标的有效手段。


首先介绍简单工厂模式的实现方式。


具体代码实现如下:

 
Person(name, age) {
var obj = {}
obj.name = name
obj.age = age
return obj
} 
var p1 = Person('jack', 25)
var p2 = Person('lily', 22)

与使用构造函数和 this 关键字的方式不同,简单工厂每次创建一个空对象,手动添加属性后返回。创建过程通过函数调用而非 new 操作符完成。这种模式主要用于替代具有相同属性的单一类,而更复杂的工厂则可以生成不同类型的对象。


静态工厂模式与水果示例

接下来通过一个水果工厂的示例来深入说明。


相关代码如下:

 
function Banana() {
this.price = '$1.5'
} 
function Apple() {
this.price = '$1.2'
} 
function Orange() {
this.price = '$2.2'
} 
// 静态工厂类
function Fruit() {}
Fruit.factory = function(type) {
if (!window[type]) {
return
} 
var fruit = new window[type]
return fruit
} 
// 制造不同的水果
var banana = Fruit.factory('Banana')
var apple = Fruit.factory('Apple')
var orange = Fruit.factory('Orange')

该示例包含 Banana、Apple 和 Orange 三个水果类,以及一个 Fruit 工厂类。通过静态方法 factory,根据传入的类型参数动态创建并返回对应的水果对象实例。


原生对象中的工厂模式应用

工厂模式的思路在 JavaScript 原生对象 Object 中也有体现,例如:


具体代码示例如下:

 
var obj = Object(),
num = Object(1),
str = Object('s'),
boo = Object(false);

Object 充当了工厂的角色,根据传入参数的不同构造出不同类型的对象。obj 生成空对象,num 生成 Number 类型对象,str 生成 String 类型对象,而 boo 生成 Boolean 类型对象。


此外,jQuery.Callbacks 也是一个典型的工厂实现。每次调用它都会返回一个包含 add、remove、fire 等方法的对象。通过传入 'once'、'memory' 等参数,还可以构造出具有不同行为特性的对象实例。



简而言之,工厂模式是指一种能够返回对象的方法或函数。


利用工厂模式扩展 DOM 对象

利用这种模式,我们可以扩展现有 DOM 对象的方法。例如,若希望为 DOM 节点增加一个名为 sayHello 的自定义方法,可以按以下方式实现:


代码实现如下:

 
function RemouldNodeObj(DomNode){
//先判断一下传递进来的参数是不是一个Dom节点
if(typeof DomNode == "object" && DomNode.nodeType == 1){
DomNode.say = function(){
alert("Hello!!");
} 
}else{
alert("你传递进来的参数不正确!");
} 
} 
//这样调用:
window.onload = function(){
var oDiv = RemouldNodeObj(document.getElementById("test"));
//通过这一步,oDiv就拥有了新的方法say
oDiv.say();
} 

基于上述基础,我们可以实现更复杂的功能,例如通过 JavaScript 调用生成一个简单的 form 表单。具体代码如下:


相关代码示例:

 
<html>
<head>
<title>JavaScript之工厂模式</title>
<script type="text/javascript">
function RemouldNodeObj(DOMnode){
//先判断一下传递进来的参数是不是一个Dom节点
if(typeof DOMnode == "object" && DOMnode.nodeType == 1){
DOMnode.createForm = function(opt){
//下面是一大串的字符串加法,只是为了拼装出form元素
var oForm = "";
oForm += "<form action=\"" + opt.action + "\" ";
oForm += "method=\"" + (opt.method || 'GET') + "\" id=\"";
oForm += (opt.id || "") + "\"";
oForm += "style=\"width:200px;height:30px;border:2px solid #223344\">";
oForm += "</form>";
//这里的this不要想得太复杂,谁调用就指向谁,所以this指向 oDiv
this.innerHTML = oForm;
} 
}else{
alert("参数不正确!");
} 
return DOMnode;
} 
//这样调用
window.onload = function(){
var oDiv = RemouldNodeObj(document.getElementById("custom"));
oDiv.createForm({
'action' : 'index.jsp',
'method' : 'post',
'id' : 'myForm'
}); 
} 
</script>
</head>
<body>
<div id="custom">###</div>
</body>
</html>

这种调用方式与 jQuery 的风格非常相似。如果解决了跨浏览器兼容性问题,完全可以基于此开发出一个搜索栏插件。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章