标签:javascript 单例 设计模式
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/30490955
一直很喜欢Js,,,今天写一个Js的单例模式实现以及用法。
单例模式写法相当简单:
var singleTon = { m1: "memeber first ", m2: "memeber second ", f1: function () { console.log("fun1 "); } };
在开发中一个页面一般会引入多个Js文件,甚至这多个文件多人写的,大家都可能在全局定义init这个方法,都可能在全局声明name这是属性。这样的话就造成的命名的冲突,发生一些意想不到的问题。所以我们需要引入命名空间:
我们可以让每个程序猿写的Js在他自己的命名空间下:
/** * 创建命名空间 * @type {{}} */ var ZhangHongYang = {}; var zhy = {}; zhy.com = {} ; zhy.com.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>
<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>
上述单例的写法,会把所有的方法与变量暴露给使用者, 如何设置私有变量或者私有方法。
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(); } }; })();
在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>
我们的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)); } }; })();
调用的代码:
<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中供编辑;如果各位项目中没有考虑到这类问题,首先你可以测试下问题,然后可以使用上面的代码解决这类问题。
相信大家都了解过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 ; }
我们把代码改成:
/** * 用于在程序加载次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的文件基本在引入页面后,浏览器加载就会进行大量操作占用内存,有时候我们希望等到我们去使用时再去执行一些操作,如果从未使用就省去不必要的内存消耗,我们可以进行如下改写代码:
/** * 用于在程序加载次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>
好了,js的单例模式已经常用的方法介绍完了,以后在书写js代码时,可以尝试使用上述的方法进行书写,而不是大量定义全局function以及变量,请不要在html标签中增加事件处理的代码~
如果存在任何问题,或者有任何问题请留言~
Javascript 设计模式 单例,布布扣,bubuko.com
标签:javascript 单例 设计模式
原文地址:http://blog.csdn.net/lmj623565791/article/details/30490955