JavaScript 工厂模式详解:从简单实现到 DOM 扩展应用
本文深入解析 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 的风格非常相似。如果解决了跨浏览器兼容性问题,完全可以基于此开发出一个搜索栏插件。
JavaScript将图片转换为Base64编码的两种途径
2026-11-05 16:43:05
怎么在 Vue 或 React 项目中正确集成 animate.js
2026-11-05 10:23:38
JS注册事件:addEventListener基础语法与参数详解
2026-11-05 08:44:56
JSP和JS的区别:运行环境与服务端/客户端职责解析
2026-11-04 23:34:36
pdf.js 官方下载地址:GitHub Release 获取预编译包
2026-11-04 23:07:27
