JavaScript设计模式详解:工厂模式与构造器模式实战
本文深入解析JavaScript中的两种核心创建型设计模式:工厂模式与构造器模式。文章首先梳理了常见反模式,随后通过具体代码示例演示了工厂模式在解决实例化重复问题上的应用及其局限性,并详细阐述了构造器模式如何通过new关键字和原型链实现对象识别与内存优化,帮助开发者掌握不同场景下的最佳实践。
JavaScript设计模式概述与反模式
设计模式
此前因准备期末考试,精力有限未能及时更新,今日与大家探讨JavaScript中的设计模式。
首先明确概念:模式指可复用的解决方案,而反模式则是针对特定问题的不良处理方案。
JavaScript常见反模式示例
1. 向setTimeout和setInterval传递字符串而非函数,这会隐式调用eval(),存在安全风险。 2. 在全局上下文中定义大量变量,导致全局命名空间污染。 3. 修改Object类的原型,可能引发不可预知的兼容性问题。 4. 在HTML中以内联形式使用JavaScript,此类代码难以被外部单元测试工具覆盖。 5. 滥用document.write,若在页面加载完成后执行,会重写当前页面;建议优先使用document.createElement。
设计模式的分类
创建型设计模式
创建型设计模式关注对象创建的机制,旨在以适配特定情境的方式创建对象。该类别包含以下属性:
Constructor(构造器)、Factory(工厂)、Abstract(抽象)、Prototype(原型)、Singleton(单例)和Builder(生成器)。
结构型设计模式
结构型模式涉及对象组合,通常用于发现建立对象间关系的简易方法。 属于该类别的模式包括:
Decorator(装饰者)、Facade(外观)、Flyweight(享元)、Adapter(适配器)和Proxy(代理)。
行为设计模式
行为模式专注于改进或简化系统中不同对象间的通信机制。
行为模式包括:
Iterator(迭代器)、Mediator(中介者)、Observer(观察者)和Visitor(访问者)。
工厂模式原理与实战
Factory(工厂)模式
为解决多个类似对象声明导致的实例化重复问题,可采用工厂模式。该方法旨在集中处理对象创建,减少代码冗余。
示例代码如下:
<script type="text/javascript">
function createObject(name,age,profession){//集中实例化的函数
var obj = new Object();
obj.name = name;
obj.age = age;
obj.profession = profession;
obj.move = function () {
return this.name + ' at ' + this.age + ' engaged in ' + this.profession;
};
return obj;
}
var test1 = createObject('trigkit4',22,'programmer');//第一个实例
var test2 = createObject('mike',25,'engineer');//第二个实例
alert(test1.move());
alert(test2.move());
</script>
工厂模式的分类
工厂模式分为简单工厂、抽象工厂和智能工厂,其特点是不显式要求使用构造函数。
简单工厂模式:使用一个类(通常为单体)来生成实例。 复杂工厂模式:使用子类来决定一个成员变量应该是哪个具体的类的实例。
工厂模式的优势
主要好处在于消除对象间的耦合,通过工程方法替代new关键字,并将所有实例化代码集中在一个位置以防止代码重复。 工厂模式的劣势
大多数类使用new关键字和构造函数可使代码更简单易读,无需查看工厂方法即可理解。工厂模式虽解决了重复实例化问题,但存在识别问题,即难以判断对象的具体类型。
验证代码如下:
alert(typeof test1); //Object
alert(test1 instanceof Object); //true
何时使用工厂模式?
Factory模式主要适用于以下场景:
1. 当对象或组件涉及高复杂性时 2. 当需要根据不同环境轻松生成对象的不同实例时 3. 当处理许多共享相同属性的小型对象或组件时
构造器模式与原型链应用
Constructor(构造器)模式
ECMAScript中可采用构造函数(构造方法)来创建特定对象。该模式有效解决了工厂模式无法识别对象实例的问题。
示例代码如下:
<script type="text/javascript">
function Car(model,year,miles){//构造函数模式
this.model = model;
this.year = year;
this.miles = miles;
this.run = function () {
return this.model + " has done " + this.miles + "miles";
}
}
var Benz = new Car('Benz',2014,20000);
var BMW = new Car("BMW",2013,12000);
alert(Benz instanceof Car); //很清晰的识别他从属于 Car,true
console.log(Benz.run());
console.log(BMW.run());
</script>
使用构造函数方法既解决了重复实例化问题,又解决了对象识别问题。该模式与工厂模式的不同之处在于:
1. 构造函数方法没有显式创建对象 (new Object()); 2. 直接将属性和方法赋值给 this 对象; 3. 没有 return 语句。
构造函数的方法有一些规范:
1. 函数名和实例化构造名相同且大写, (PS:非强制,但这么写有助于区分构造函数和 普通函数); 2. 通过构造函数创建对象,必须使用 new 运算符。 既然通过构造函数可以创建对象,那么这个对象是哪里来的, new Object()在什么地方执行了?执行的过程如下:
1. 当使用了构造函数,并且 new 构造函数(),那么就后台执行了 new Object(); 2. 将构造函数的作用域给新对象 ,(即 new Object()创建出的对象),而函数体内的 this 就 代表 new Object()出来的对象。 3. 执行构造函数内的代码; 4. 返回新对象(后台直接返回)。
带原型的Constructor(构造器)
js中有一个名为prototype的属性。调用js构造器创建一个对象后,新对象就会具有构造器原型的所有属性。通过这种方式,可以创建多个Car对象,并访问相同的原型。
示例代码如下:
<script type="text/javascript">
function Car(model,year,miles) {
this.model = model;
this.year = year;
this.miles = miles;
}
Car.prototype.run = function () {
return this.model + " has done " + this.miles + " miles ";
};
var Benz = new Car('S350',2010,20000);
var Ford = new Car('Ford',2012,12000);
console.log(Benz.run());//"S350 has done 20000 miles "
console.log(Ford.run());
</script>现在run()的单一实例就能够在所有Car对象之间共享。
JavaScript闭包与类(Class)的区别及适用场景对比
2026-11-05 15:48:57
JavaScript入门要学ES6吗?let与箭头函数等新特性解析
2026-11-05 14:49:16
JavaScript 8种数据类型详解:基本类型与引用类型的区别
2026-11-05 14:25:15
怎么在JavaScript中使用async/await优化Ajax异步流程
2026-11-05 13:56:15
JavaScript replace回调函数实现动态正则替换逻辑
2026-11-05 13:52:13
