转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/30490955

一直很喜欢Js,,,今天写一个Js的单例模式实现以及用法。

1、单例模式的写法

单例模式写法相当简单:

     var singleTon = {
m1: "memeber first ",
m2: "memeber second ",
f1: function ()
{
console.log("fun1 ");
}
};

好了,结束了,其实就是字面量创建对象的方式,很简单吧。如果你觉得单例太简单,不用看了,那你就错了,单例在Js中用的地方挺多,话说你经常用么~。

2、单例用法一:创建命名空间

在开发中一个页面一般会引入多个Js文件,甚至这多个文件多人写的,大家都可能在全局定义init这个方法,都可能在全局声明name这是属性。这样的话就造成的命名的冲突,发生一些意想不到的问题。所以我们需要引入命名空间:

我们可以让每个程序猿写的Js在他自己的命名空间下:

/**
* 创建命名空间
* @type {{}}
*/
var ZhangHongYang = {}; var zhy = {};
zhy.com = {} ;
zhy.com.js = {};

比如以每个人的名字作为命名空间,之后写方法就:ZhangHongyang.xxx();或者你习惯了Java的命名空间,也可以zhy.com.js.xxx。

3、单例实例:实现一个注册页面的Js

针对像注册页面上的Js,一般都是针对此页面写的,建议使用单例的方式书写。

下面的展示如何使用单例的写法,实现ajax的注册功能,当然没有服务器,模拟一下:

html:

<body>
<form action="user/register" id="registerForm"> <div>
<label for="username">username</label>
<input type="text" name="username" id="username"/>
</div>
<div>
<label for="nickname">nickname</label>
<input type="text" name="nickname" id="nickname"/>
</div>
<div>
<label for="password">password</label>
<input type="text" name="password" id="password"/>
</div> <div>
<input type="submit" value="Register"/>
</div>
</form> <div id="registerResult" style="width: 400px;height: 200px;border: 1px solid #444;"> </div> </body>

当用户点击submit,会进行一些列的处理,最终将数据展示到registerResult中:

 <script type="text/javascript">

        /**
* 单例的用法:
* 有时候我们需要针对某个页面进行写Js,比如登录页面,建议使用下列方式:
* ZhangHongyang,singlePageJsForRegiste =
* {
* CONSTANT1:"",
* CONSTANT2:"",
* f1:function(){},
* f2:function(){}
* }
*/ ZhangHongYang.singlePageJsForRegister =
{
ID_FROM: "registerForm",
ID_RESULT_CONTAINER: "registerResult",
init: function ()
{
ZhangHongYang.singlePageJsForRegister.form = $("#" + this.ID_FROM);
ZhangHongYang.singlePageJsForRegister.result = $("#" + ZhangHongYang.singlePageJsForRegister.ID_RESULT_CONTAINER);
this.form.submit(this.handleSubmit);
},
handleSubmit: function (event)
{ var datas = {};
ZhangHongYang.singlePageJsForRegister.form.find("input").each(function (i)
{
//omitted the unnecessary datas
if (!($(this).attr("type") == "button" || $(this).attr("type") == "submit" || $(this).attr("type") == "reset" ))
{
datas[$(this).attr("name")] = $(this).val();
}
});
ZhangHongYang.singlePageJsForRegister.ajaxSubmit(datas);
//prevent the default form submit
event.preventDefault();
},
ajaxSubmit: function (datas)
{
var url = ZhangHongYang.singlePageJsForRegister.form.attr("action");
console.log("url :" + url);
//make ajax submit here
//$.post(url,datas,function(data){});
//show result
ZhangHongYang.singlePageJsForRegister.showResult(datas);
},
showResult: function (datas)
{
var result = "";
for (var p in datas)
{
result += p + " = " + datas[p] + "<br/>";
}
ZhangHongYang.singlePageJsForRegister.result.html(result);
}
}; $(function ()
{
ZhangHongYang.singlePageJsForRegister.init();
}); </script>

我们使用单例定义了一个singlePageJsForRegister方法对象,然后将需要用到的元素的Id作为了常量,然后通过init初始化事件等,还有其他的几个函数,代码中也书写了注释。看了上面的代码可能觉得这么写好复杂,代码量也多了,但是对于Js的提升,要慢慢的学习面向对象以及结构化的写法,不能在script标签中,不断的定义各种方法,甚至在html标签中书写onclick这类的属性。Js一定要保证,html与js文件解耦;js代码整体上结构清晰;学习使用面向对象的方式处理问题。

4、如何在单例创建的对象中,定义私有方法和属性

上述单例的写法,会把所有的方法与变量暴露给使用者, 如何设置私有变量或者私有方法。

a、采用约定的方式:所有以_开头的方法和变量都是私有变量。

  /**
* 方式一
* 采用约定,所有以_开头的变量或者方法为私有变量
*/
var singleTon = {
_m1: "hello",
_f1: function ()
{
},
init: function ()
{
}
};

可以觉得方式1不是自己骗自己么,但是项目嘛,约定由于配置,也是可行的。实在觉得不能忍受,看方式二:

 /**
* 方式二
*/
var singleTon = (function ()
{
var _m1 = "hello";
var _f1 = function ()
{
console.log(" i am a private function !");
} return {
//public method
init: function ()
{
//invoke the private method in the singleTon
_f1();
}
}; })();

采用了闭包的方式,很好的实现了私有变量和私有方法的隐藏。

5、单例实例:解决Textarea的数据存储时的Html转Txt和展示时Txt转Html

在web项目中,很多情况会使用到Textarea。

a、比如留言、技能的书写等;对于这类Textarea我们有必要对用户输入的html代码做特殊处理,防止用户填写恶意代码或者把页面的样式弄乱。

b、相反来说,在Textarea中书写的换行以及空格,最终在div中显示却没有效果,都是一个空格,所有很多web开发者会选择使用只读textarea来回显用户输入内容,其实需要做一定的转换。

html:

<body>
<textarea style="width: 400px;height: 120px;" id="taContent">
</textarea> <input type="button" id="convert" value="Convert"/>
<br/>
<br/> <fieldset style="width: 400px">
<legend>html转化为Txt,供Div展示</legend>
<div style="width: 400px;height: 120px;border: 1px solid #555;" id="divContent"> </div>
</fieldset> <br/>
<br/> <fieldset style="width: 400px">
<legend>Txt转化为Html,供Textarea修改</legend>
<textarea style="width: 400px;height: 120px;" id="taEdit">
</textarea>
</fieldset> </body>

第一个Textarea用于用户输入,然后经过转义显示到div中,然后将转义后的数据进行逆向恢复显示到第二个TextArea中。相当与模拟了,div中展示数据和用户再次编辑数据,这些功能在项目中都相当实用。

我们的js代码:

  /**
* 对用户在TextArea中输入的数据进行过滤,把< -> <等操作,以及逆向操作
*/
ZhangHongYang.htmlFilter = (function ()
{
/**
* 转化textarea中的空格为$nbsp;
* \n转化为<br/>
* @private
*/
function _transSpace(data)
{
return data.replace(/\n/g, "<br/>").replace(/\s/g, " ");
}; /**
* 转化所有尖括号
* @private
*/
function _transBrace(data)
{
return data.replace(/</g, "<").replace(/>/g, ">");
}; function _resumeSpace(data)
{
return data.replace(/ /g, " ").replace(/<br\s*\/>/ig, "\n");
};
function _resumeBrace(data)
{
return data.replace(/</g, "<").replace(/>/g, ">");
}; return { txt2Html: function (data)
{
return _transSpace(_transBrace(data)); }, html2Txt: function (data)
{
return _resumeSpace(_resumeBrace(data));
}
}; })();

在我的命名空间下定义了htmlFilter方法,然后最后暴露两个方法Html2Txt和Txt2Html给使用者。

调用的代码:

    <script type="text/javascript">
$(function ()
{
$("#convert").click(function ()
{
var txt = ZhangHongYang.htmlFilter.txt2Html($("#taContent").val());
console.log(txt);
$("#divContent").html(txt);
$("#taEdit").val(ZhangHongYang.htmlFilter.html2Txt(txt));
});
});
</script>

效果图:

可以看到换行、空格、以及恶意的HTML代码等都得到了很好的在DIV中的显示;且最终可还原为Textarea中供编辑;如果各位项目中没有考虑到这类问题,首先你可以测试下问题,然后可以使用上面的代码解决这类问题。

6、单例写法提高多分支代码效率

相信大家都了解过ajax,对象ajax肯定离不开XMLHttpRequest,而且不同版本、类型的浏览器创建方式不一致。一般我们可能会这么写创建XMLHttpRequest的方法:

  function createXhr()
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
} return xmlhttp ;
}

存在一个问题,每次创建XHR对象都需要进行分支判断,如果某个方法分支特别多,我们可以做进一步的优化,当浏览器加载js文件时,就决定以后调用只会用其中合适的方式,而不会走分支。

我们把代码改成:

   /**
* 用于在程序加载次js文件时,根据当前浏览器返回一个创建xhr的工厂方法,而不需要每次都去分支判断
*/
ZhangHongYang.xhrFactroy = (function ()
{
function _ieCreateXhr()
{ // code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
} function _newCreateXhr()
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
} if (window.XMLHttpRequest)
{
return _newCreateXhr;
}
else
{
return _ieCreateXhr;
}
})();

当程序加载完成js文件后,会自动根据浏览器类型返回适合的方法,避免每次都会进行分支判断,我们只需要使用ZhangHongYang.xhrFactroy();创建XHR对象。

7、单例引入懒加载功能

上述的js的文件基本在引入页面后,浏览器加载就会进行大量操作占用内存,有时候我们希望等到我们去使用时再去执行一些操作,如果从未使用就省去不必要的内存消耗,我们可以进行如下改写代码:

/**
* 用于在程序加载次js文件时,根据当前浏览器返回一个创建xhr的工厂方法,而不需要每次都去分支判断
*/
ZhangHongYang.xhrFactroy = (function ()
{
var _instance = null; function _constructor()
{
function _ieCreateXhr()
{ // code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
} function _newCreateXhr()
{
// code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
} if (window.XMLHttpRequest)
{
return _newCreateXhr;
}
else
{
return _ieCreateXhr;
}
} return {getInstance: function ()
{
if (_instance == null)
{
_instance = _constructor();
}
return _instance; }}; })();
<script type="text/javascript">

        var xhrFactoryMethod = ZhangHongYang.xhrFactroy.getInstance();
console.log(xhrFactoryMethod()); </script>

只有使用时才会去执行_constructor()方法,而不是我们之前的一加载完成就执行。

好了,js的单例模式已经常用的方法介绍完了,以后在书写js代码时,可以尝试使用上述的方法进行书写,而不是大量定义全局function以及变量,请不要在html标签中增加事件处理的代码~

如果存在任何问题,或者有任何问题请留言~

版权声明:本文为博主原创文章,未经博主允许不得转载。

Javascript 设计模式 单例的更多相关文章

  1. javascript学习(9)——[设计模式]单例

    单例模式,相信大家对此都不陌生,我们主要讲下javascript中几个比较常见的设计模式: (1).普通的单体 (2).具有局部变量的强大单体 (3).惰性单体 (4).分支单体 下面我们就一一进行介 ...

  2. 【java】设计模式-单例设计模式

    单例设计模式:解决一个类在内存中是存在一个对象的问题.当需要该事物的对象在内存中唯一时,将以下三步添加即可. 思想:想要保证对象唯一1.为了避免其他程序过多的建立该类对象,先禁止其他程序建立该类对象2 ...

  3. java设计模式--单例

    GOF23(group of four)---由4个大牛总结的JAVA23种常用的设计模式,归根结底都是为了代码的可扩展性. 设计模式中一种比较重要的思想就是:开闭原则,尽量做到对扩展开放,对修改关闭 ...

  4. javascript的单例/单体模式(Singleton)

    首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点:1,该类只有一个实例2,该类自行创建该实例(在该类内部创建自身的实例对象)3,向整个系统公开这个实例接口 Java中大概是这 ...

  5. java软件设计模式——单例设计模式中的【饿汉式】与 【懒汉式】示例

    以下为单例设计模式中的两种经典模式的代码示意: 单例设计模式(spring框架IOC,默认创建的对象都是单例的): 饿汉式: public class SingleClass { private Si ...

  6. C#设计模式——单例

    单例模式是设计模式中最简单的形式之一.这一模式的目的是使得类的一个对象成为系统中的唯一实例.对于系统中的某些类来说,只有一个实例很重要,例如,一个系统中可以存在多个打印任务,但是只能有一个正在工作的任 ...

  7. php设计模式-单例

    单例模式是一种常用的软件设计模式.在它的核心结构中只包含一个被称为单例的特殊类.通过单例模式可以保证系统中一个类只有一个实例. <设计模式>对此的定义:保证一个类仅有一个实例,并提供一个访 ...

  8. java设计模式——单例设计模式

    /*设计模式:对问题行之有效的解决方式.其实它是一种思想. 1,单例设计模式.    解决的问题:就是可以保证一个类在内存中的对象唯一性. 必须对于多个程序使用同一个配置信息对象时,就需要保证该对象的 ...

  9. Java设计模式—单例设计模式(Singleton Pattern)全然解析

    转载请注明出处:http://blog.csdn.net/dmk877/article/details/50311791 相信大家都知道设计模式,听的最多的也应该是单例设计模式,这种模式也是在开发中用 ...

随机推荐

  1. DB Query Analyzer 6.01 is released, SQL Execute Schedule function can be used

       DB Query Analyzer is presented by Master Gen feng, Ma from Chinese Mainland. It has English versi ...

  2. ASP.NET Provider模式应用之SqlMembershipProvider类的剖析

    太多了,先给个流程图吧 Provider模式就是GOF中的两种设计模式的应用:策略模式和工厂模式,在程序中使用好这个模型能够解除模块与模块之间的耦合甚至是DIP,同时,不管是ASP.NET MVC还是 ...

  3. Java IO学习--(五)字节和字符数组

    内容列表 从InputStream或者Reader中读入数组 从OutputStream或者Writer中写数组 在java中常用字节和字符数组在应用中临时存储数据.而这些数组又是通常的数据读取来源或 ...

  4. minimun path sum(最小路径和)

    Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which ...

  5. 发现DELL笔记本一个很弱智的问题

    以前用联想的笔记本,最近联想笔记本坏了,用的是公司的DELL笔记本,发现DELL笔记本一个很弱智的问题. 关于禁用触摸板的问题. 起因: 由于要经常写程序,我配置的有有线鼠标,但是打字时经常碰到触摸板 ...

  6. Android Java端的Socket.io-client

    先讲讲历史,这个方面最早的应该是nkzawa@github的项目:http://mvnrepository.com/artifact/com.github.nkzawa/socket.io-clien ...

  7. linux常用命令合集(未完)

    (1)新建 新建文件夹:mkdir 文件夹名 新建文件:touch 文件路径/文件名 删除: rm –f filename删除文件 rm –rf filename删除文件夹 (2)重命名 1将一个名为 ...

  8. C# 操作PDF 图层(Layer)——添加、删除图层、设置图层可见性

    前言 通过添加图层,我们可以将文本.图片.表格.图形等元素精确定位于页面指定位置,将这些元素进行叠放.组合形成页面的最终效果.此外,对于页面中已有的图层我们也可以进行设置图层可见性.删除图层等操作.因 ...

  9. Git忽略远程已存在的文件

    git设置本地忽略时远程上不存在本地忽略的文件,git将忽略.如果远程分支上存在这个文件,本地在设置ignore将不起作用.换句话说git本地忽略文件必须保证git的远程仓库分支上没有这个要忽略的文件 ...

  10. 物流的纯css实现方法

    首先我们来看看UI给出的设计图. 为什么到达是最前面,为什么物流顺序是倒叙的,这是什么用户习惯,这是我拿到设计稿的问题,但是这里不谈设计,因为审美这个东西无法评估.那么这里我就做一个顺序的来对比一下吧 ...