01单例模式

首先看一个问题,我们要在程序中描述两个人,这两个人都有姓名和年龄,可能刚刚开始学习js的时候会写成这样:

 var name1 = 'iceman';
var age1 = 25; var name2 = 'mengzhe';
var age2 = 26;

以上的写法的确是描述两个人,每个人都有姓名和年龄,但是每个人的姓名和年龄并没有放在一起,也就是说每个人的年龄和姓名并没有对应起来。这时候我们就引出对象的概念:把描述同一个事物(同一个对象)的属性和方法放在同一个内存空间下面,起到了分组的作用,这样不同事物之间的属性即使属性名相同相互也不会发生冲突。

 var person1 = {
name:'iceman',
age:25}; var person2 = {
name:'mengzhe',
age:26};

以上这种写法可以认为是一种分组编写代码的模式,通过如此分组之后,每一个人的姓名和年龄都在同一块内存空间下,也就是每个人的姓名和年龄都对应起来了。我们也把这种分组编写代码的模式称之为单例模式(在《JavaScript高级程序设计》中也称之为对象字面量模式),在单例模式中,把person1和person2叫做命名空间。

单例模式是一种项目开发中经常使用的模式,因为项目中我们可以使用单例模式来进行模块化开发,对一个相对来说比较大的项目中,需要多人协作开发,所以一般情况下会根据当前项目的需求,划分几个功能模块,每个人负责一部分,同时开发,最后把每个人的代码进行合并,比如:

公共模块:提供公共方法

 var utils = {
select:function () {
//...
}
};

页面选项卡模块:实现选项卡切换

 var tabModule = {
change:function () {
utils.select(); // 在自己的命名空间下调用其他命名空间的方法
}
};

搜索模块:实现搜索内容变化的处理

 var searchModule  = {
change:function () {
this.clickEvent(); // 在自己的命名空间下调用自己命名空间的方法
},
clickEvent:function () {
//...
}
};

以上在例子中,在选项卡模块(tabModule)和和搜索模块(searchModule)中都有change方法,如果没有分模块来编写的话会造成命名的冲突,按照JavaScript语言的解析规则,后声明的方法会覆盖前面声明的方法。而通过模块划分之后,这两个模块下的change方法归属于各自的模块,调用的时候都是调用自己模块下的方法(tabModule.change()、searchModule.change()),不会有冲突。

02工厂模式

回顾单例模式:
 var person1 = {
name:'iceman',
age:25,
writeJs:function () {
console.log(this.name + 'write js');
}
};
person1.writeJs();

单例模式解决了分组的问题,让每个对象有了自己独立的命名空间,但是不能批量生产,每一个新的对象都要重新写一份一模一样的代码。这时候就有了工厂模式,即:把实现同一事情的相同代码,放到一个函数中,以后如果再想实现这个功能,就不需要重新编写这些代码了,只要执行当前的函数即可,这就是函数的封装,体现了高内聚、低耦合的思想:减少页面的中的冗余代码,提高代码的重复利用率:

 function createPerson(name, age) {
var obj = {};
obj.name = name;
obj.age = age;
obj.writeJs = function () {
console.log(this.name + 'write js');
} return obj;
} var p1 = createPerson('mengzhe' , 26);
p1.writeJs(); var p2 = createPerson('iceman' , 25);
p2.writeJs();

顺便讲一下重载:在Java、C#等强类型的面向对象编程语言中,有函数重载的概念,但是在JavaScript中不存在重载,如果方法名一样的话,后面的会把前面的覆盖掉,最后只保留一个方法的定义,不过我们可以根据传递的参数不一样,实现模拟重载的功能:

 function sum(num) {    if (typeof num === 'undefined') {        return 0;
} return num;
}
sum(100);
sum();

03构造函数模式

 function CreateJsPerson(name, age) {
this.name = name;
this.age = age;
this.writeJs = function () {
console.log(this.name + 'write js');
}
// 浏览器再把创建的实例默认的进行返回
}
var p1 = new CreateJsPerson('iceman' , 25);
p1.writeJs();
var p2 = new CreateJsPerson('mengzhe' , 26);
p2.writeJs();

注意:上面是new CreateJsPerson('iceman' , 25)这样,使用了new创建了对象,这和普通调用函数的方式有区别的:

 var res = CreateJsPerson('xx' , 7);

这样没有用new而直接调用函数的方式,不是构造函数而是普通函数执行,由于没有写return,所以res=undefined,并且CreateJsPerson这个方法中的this是window。

构造函数模式的目的就是为了创建一个自定义类,并且创建这个类的实例。

构造函数模式和普通函数的模式的区别:

执行的时候

  • 普通函数执行:CreateJsPerson()

  • 构造函数执行:new CreateJsPerson(),通过new执行后,CreateJsPerson就是一个类了,而函数的返回值就是CreateJsPerson这个类的一个实例。

在函数代码执行的时候

  • 相同:都是形成一个私有的作用域,然后经历:形参赋值 --> 预解释 --> 代码从上到下执行(类和普通的函数一样执行,它也有普通函数的一面)。

  • 不同:① 在构造函数的代码执行之前,不用自己再手动的创建对象,浏览器会默认的创建一个对象数据类型的值(这个对象类型的值其实就是当前类的一个实例);② 接下来代码从上到下执行,以当前实例为执行的主体(this代表的就是当前的实例),然后分别的把属性名和属性值赋值给当前的实例;③ 最后,浏览器会默认的把创建的实例返回。

注意点:

  • JavaScript中所有的类都是函数数据类型的,它通过new执行变成了一个类,但是它本身也是一个普通的函数;

  • JavaScript中所有的实例都是对象数据类型的;

  • 在构造函数模式中,类中(函数体中)出现的 this.xx = xx中的this是当前类的一个实例;

  • p1和p2都是CreatePerson这个类的实例,所以都拥有writeJs这个方法,但是不同实例之间的方法是不一样的,在类中给实例增加的属性(this.xxx=xxx)属于当前实例的私有的属性,实例和实例之间是单独的个体,所以私有的属性之间是不相等的。

     console.log(p1.writeJs === p2.writeJs); // --> false

JavaScript 创建对象之单例、工厂、构造函数模式的更多相关文章

  1. php : MVC 演示(使用单例工厂)

    此例子是MVC的简单应用, 要达到的效果如下: 用户列表: 姓名 年龄 学历 兴趣 出生地 账号创建时间 操作 keen 20 高中 篮球,足球 广东 2016-11-08 10:00:31 删除 a ...

  2. Redis 单例、主从模式、sentinel 以及集群的配置方式及优缺点对比(转)

    摘要: redis作为一种NoSql数据库,其提供了一种高效的缓存方案,本文则主要对其单例,主从模式,sentinel以及集群的配置方式进行说明,对比其优缺点,阐述redis作为一种缓存框架的高可用性 ...

  3. 如何将业务代码写得像诗一样(使用注解+单例+工厂去掉一大波if和else判断)

    1.订单控制器,提供一个根据商品id和银行渠道id计算商品折后价格的接口: import org.springframework.web.bind.annotation.GetMapping; imp ...

  4. JavaScript构造函数+原型创建对象,原型链+借用构造函数模式继承父类练习

    虽然经常说是做前端开发的,但常常使用的技术反而是JQuery比较多一点.在JavaScript的使用上相对而言少些.尤其是在创建对象使用原型链继承上面,在项目开发中很少用到.所以今天做个demo练习一 ...

  5. PHP设计模式之工厂/单例/注册者模式

    工厂模式 简单工厂模式 [静态工厂方法模式](Static Factory Method)是类的创建模式 工厂模式的几种形态: 1.简单工厂模式(Simple Factory)又叫做 静态工厂方法模式 ...

  6. JavaScript之面向对象学习六原型模式创建对象的问题,组合使用构造函数模式和原型模式创建对象

    一.仔细分析前面的原型模式创建对象的方法,发现原型模式创建对象,也存在一些问题,如下: 1.它省略了为构造函数传递初始化参数这个环节,结果所有实例在默认的情况下都将取得相同的属性值,这还不是最大的问题 ...

  7. Swift百万线程攻破单例(Singleton)模式

    一.不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法.单例的实现有多种方法,如下面: class SwiftSingleton { class var shared ...

  8. Redis单例、主从模式、sentinel以及集群的配置方式及优缺点对比

    https://my.oschina.net/zhangxufeng/blog/905611

  9. 适配器、工厂模式、线程池、线程组、互斥锁、Timer类、Runtime类、单例设计模式(二十四)

    1.多线程方法 * Thread 里面的俩个方法* 1.yield让出CPU,又称为礼让线程* 2.setPriority()设置线程的优先级 * 优先级最大是10,Thread.MAX_PRIORI ...

随机推荐

  1. 使用ajax爬取网站图片()

    以下内容转载自:https://www.makcyun.top/web_scraping_withpython4.html 文章关于网站使用Ajaxj技术加载页面数据,进行爬取讲的很详细 大致步骤如下 ...

  2. windows 下关于nginx的操作

    在nginx安装目录下操作 1.启动:start nginx 2.停止:① nginx.exe -s stop ②nginx.exe -s quit   注:stop是快速停止nginx,可能并不保存 ...

  3. Syncfusion在WinPhone8.1实现统计图

    using Syncfusion.UI.Xaml.Charts; public static SfChart InitCompareChart(string fundName, double tenT ...

  4. UVa 10465 Homer Simpson(DP 全然背包)

     题意 霍默辛普森吃汉堡  有两种汉堡  一中吃一个须要m分钟  还有一种吃一个须要n分钟  他共同拥有t分钟时间    要我们输出他在尽量用掉全部时间的前提下最多能吃多少个汉堡  假设时间无法用 ...

  5. POJ 3280 Cheapest Palindrome DP题解

    看到Palindrome的题目.首先想到的应该是中心问题,然后从中心出发,思考怎样解决. DP问题通常是从更加小的问题转化到更加大的问题.然后是从地往上 bottom up地计算答案的. 能得出状态转 ...

  6. 【JavaScript】——JS入门

    结束XML之旅,開始JavaScript的学习,看视频.了解了她的前世今生,还是为她捏了把汗啊! 看了部分视 频了,简单的总结一下吧! JavaScript是什么? JavaScript是一种基于面向 ...

  7. HTML5和CSS3中的交互新特性

    当文章的标题是一副用photoshop制作的图片,那么势必在搜索引擎中无法搜索到.并且因为图片的体积不算小.可能在网速慢的的时候不得不耐心的等待图片的刷新. 所以.我们来谈谈有没有一种新的方法能够避免 ...

  8. HTTP详解工作原理

    1. HTTP简介 HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议.它可以使浏览器更加高效,使网络传输减少. ...

  9. luogu2833 等式

    题目大意 给出\(a,b,c,x_1,x_2,y_1,y_2\),求满足\(ax+by+c=0\),且\(x\in[x1,x2],y\in [y1,y2]\)的整数解有多少对. 题解 用扩展欧几里得算 ...

  10. 0x5C 数位统计DP

    怎么说,数位DP还是我的噩梦啊,细节太恐怖了. 但是这章感觉又和之前的学的数位DP有差异?(应该是用DP预处理降低时间复杂度,好劲啊,不过以前都是记忆化搜索的应该不会差多少) poj3208 f[i] ...