一般而言,在Javascript中创建对象时需要使用关键字new(按构造函数去调用),但是某些时候,开发者希望无论new关键字有没有被显式使用,构造函数都可以被正常调用,即构造函数同时还具备简单工厂的职能。Javascript的一个特性使得这种『简单工厂式的构造函数』变得可行:如果构造函数中返回了对象,无论有没有使用new关键字,最终返回的值都是函数return的值。

基于这点特性,本文介绍了四种实现方式,抛砖引玉,欢迎拍砖~

1. 在构造函数中返回对象字面量

 function Person(name) {
return {
name: name,
getName: function () {
return this.name;
}
};
}
console.log(new Person('Ralph').getName()); //Ralph
console.log(Person('Ralph').getName()); //Ralph

缺点:
不方便控制prototype属性,不利于高效扩展对象方法,instanceof操作符失效且constructor属性丢失

2. 在构造函数中使用内部函数构造对象

 function Person(name) {
// lazy loading,在Person函数第一次被调用时初始化内部函数_Person
if (!Person.inited) {
Person._Person = function (name) {
this.name = name;
};
// 可以利用prototype进行方法扩展
Person._Person.prototype = {
// 正常使用constructor属性
constructor: Person,
getName: function () {
return this.name;
}
};
// 可以正常使用instanceof操作符
Person.prototype = Person._Person.prototype;
// 标记为已初始化
Person.inited = true;
}
return new Person._Person(name);
}
console.log(new Person('Ralph').getName()); //Ralph
console.log(Person('Ralph').getName()); //Ralph

缺点:
编码相对较为复杂,需要_Person作为辅助的内部构造函数,且需要手动修改prototype和constructor等属性

3. 利用instanceof操作符

 function Person(name) {
// 如果使用了new,this指向新生成的Person实例
// 如果直接调用Person没有使用new,这里的this指向window对象
if (!(this instanceof Person)) {
return new Person(name);
}
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
console.log(new Person('Ralph').getName()); //Ralph
console.log(Person('Ralph').getName()); //Ralph

缺点:
在判断this instanceof Person时需要指明构造函数名称Person,抽象程度不够高,修改构造函数名称时需要手动修改该语句

4. 利用callee属性和constructor属性

 function Person(name) {
// arguments.callee指向Person函数
// this.constructor仅在使用了new的情形下指向Person函数
if (arguments.callee !== this.constructor) {
return new arguments.callee(name);
}
this.name = name;
}
Person.prototype.getName = function () {
return this.name;
};
console.log(new Person('Ralph').getName()); //Ralph
console.log(Person('Ralph').getName()); //Ralph

缺点:
strict模式下无法使用callee属性

(全文完)

Javascript将构造函数扩展为简单工厂的更多相关文章

  1. JavaScript设计模式--简单工厂模式

    一,介绍 工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类. 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口 ...

  2. Javascript设计模式理论与实战:简单工厂模式

    通常我们创建对象最常规的方法就是使用new关键字调用构造函数,这会导致对象之间的依赖性.工厂模式是一种有助于消除类之间依赖性的设计模式,它使用一个方法来决定要实例化哪一个类.本文详细介绍了简单工厂模式 ...

  3. 使用javascript完成一个简单工厂设计模式。

    在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工 ...

  4. 再起航,我的学习笔记之JavaScript设计模式05(简单工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前几 ...

  5. C#中的简单工厂和单例

    下面首先来说说简单工厂 举个例子: 首先是父类 public abstract class Pizza { public abstract string Info(); } } 子类 public c ...

  6. Design Patterns (简单工厂模式)

    文章很长很精彩,如是初学请耐心观看.(大神请绕道!) 简单工厂模式: 1.创建型模式 2.简单工厂模式概述 3.简单工厂模式的结构与实现 4.简单工厂模式的应用实例 5.创建对象与使用对象 6.简单工 ...

  7. 设计模式的征途—2.简单工厂(Simple Factory)模式

    工厂模式是最常用的一种创建型模式,通常所说的工厂模式一般是指工厂方法模式.本篇是是工厂方法模式的“小弟”,我们可以将其理解为工厂方法模式的预备知识,它不属于GoF 23种设计模式,但在软件开发中却也应 ...

  8. 用C#(.NET Core) 实现简单工厂和工厂方法模式

    本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子. 前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是 ...

  9. java之设计模式工厂三兄弟之简单工厂模式

    [学习难度:★★☆☆☆,使用频率:★★★☆☆] 工厂模式是最常用的一类创建型设计模式,通常我们所说的工厂模式是指工厂方法模式,它也是使用频率最高的工厂模式.本章将要学习的简单工厂模式是工厂方法模式的& ...

随机推荐

  1. JDK7学习笔记之基础类型

    printf()的基础用法: 变量的基础用法: 字符的输出:

  2. SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

    前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...

  3. Java 集合系列13之 WeakHashMap详细介绍(源码解析)和使用示例

    概要 这一章,我们对WeakHashMap进行学习.我们先对WeakHashMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用WeakHashMap.第1部分 WeakHashMap介绍 ...

  4. sql查询最大的见多了,查询第二的呢???

    问题:  数据库中人表有三个属性,用户(编号,姓名,身高),查询出该身高排名第二的高度. 建表语句 create table users ( id ,) primary key, name ), he ...

  5. linux vi编辑器操作手册

    简介 Linux下的文本编辑器有很多种,vi 是最常用的,也是各版本Linux的标配.注意,vi 仅仅是一个文本编辑器,可以给字符着色,可以自动补全,但是不像 Windows 下的 word 有排版功 ...

  6. 手动添加jar包到maven

    废话不说,先上图,后说明: 1.登录系统 2.跟着箭头和方框走,一直到 Select Artifact(s) to Upload... 按钮 3.点击Select Artifact(s) to Upl ...

  7. MMORPG大型游戏设计与开发(part5 of net)

    上一部分将服务器的具体代码的实现介绍给了大家,想必大家也了解到了服务器处理一次消息的复杂度.如果大家能够将各个过程掌握清楚,就会发觉其实整个逻辑与交互过程是比较清晰的.那么服务器与服务器之间的通讯,其 ...

  8. JustWeEngine - 轻量级游戏框架

    JustWeEngine - 轻量级游戏框架 An easy open source Android game engine. Github地址 引擎核心类流程图 使用方法 引入Engine作为Lib ...

  9. Java的各种工具类

    下面是java的各种工具,包括获取时间和时间比较,检验集合和字符串是否为空和长度大小等等 1 import java.io.BufferedReader; import java.io.File; i ...

  10. 编辑器插件数据保存之Serializable

    Editor数据保存需求 做编辑器插件开发时,当打开一个窗口,对数值进行修改后,在关闭窗口或重新打开Unity时,希望能保存上次的数据. 相关知识 Serialization ,ScriptableO ...