<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title><![CDATA[亮亮的博客 - javascript]]></title>
<link>http://www.94this.com.cn/</link>
<description><![CDATA[好脑袋不如乱笔头----专注web方面 asp javascri&#112;t]]></description>
<language>zh-cn</language>
<copyright><![CDATA[Copyright 2005 PBlog3 v2.8]]></copyright>
<webMaster><![CDATA[hi_94this@163.com(亮亮)]]></webMaster>
<generator>PBlog2 v2.4</generator> 
<image>
	<title>亮亮的博客</title>
	<url>http://www.94this.com.cn/images/logos.gif</url>
	<link>http://www.94this.com.cn/</link>
	<description>亮亮的博客</description>
</image>

			<item>
			<link>http://www.94this.com.cn/article/290.htm</link>
			<title><![CDATA[汉字和Unicode编码互转]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Mon,10 Aug 2009 22:12:33 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=290</guid>
		<description><![CDATA[这个是就是把汉字和Unicode编码互转的javascript代码，也是从网上找到了，也许有人用得着！！<br/><div class="UBBPanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/html.gif" style="margin:0px 2px -3px 0px"> HTML代码</div><div class="UBBContent"><TEXTAREA rows="8" id="temp69765"><script Language=Javascript>
var classObj=
     {
       ToUnicode:function(str) 
       {
        return escape(str).replace(/%/g,&#34;\\&#34;).toLowerCase();
       },
    
       UnUnicode:function(str)
       {
        return unescape(str.replace(/\\/g, &#34;%&#34;));
       },

      copyingTxt:function(str)
      {
       document.getElementById(str).sel&#101;ct(); 
       document.execCommand(&#34;Copy&#34;); 
      }
    }
</script>
<textarea id=codes style=&#34;width:500px;height:300px&#34;><&#47textarea><br><br>
<input type=button value=Unicode加密 onclick=javascript:codes.value=classObj.ToUnicode(codes.value)>
<input type=button value=Unicode解密 onclick=javascript:codes.value=classObj.UnUnicode(codes.value)>
<input type=button value=复制上面文本 onclick=javascript:classObj.copyingTxt(&#34;codes&#34;)>
<input type=button value=清空上面内容 onclick=javascript:codes.value=&#34;&#34;></TEXTAREA><br/><INPUT onclick="runEx('temp69765')"  type="button" class="userbutton" value="运行此代码"/> <INPUT onclick="doCopy('temp69765')"  type="button" class="userbutton" value="复制此代码"/> <INPUT onclick="saveCode('temp69765')" type="button" class="userbutton" value="保存此代码"><br/> [Ctrl+A 全部选择 提示：你可先修改部分代码，再按运行]</div></div>]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/284.htm</link>
			<title><![CDATA[javascript的设计模式之七[单件模式(Singleton)]]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Wed,03 Jun 2009 22:25:06 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=284</guid>
		<description><![CDATA[<strong>这篇主要对于单件模式的各种代码形式进行归纳总结。可能大家没有经意，实际上，单件模式也许是我们日常前端JS开发中使用频率最高的设计模式了。</strong><br/><strong>概述</strong><br/><br/>在软件系统中，总有一些类只能或者必须产生一个实例对象，比如线程池，缓存，注册表等等；对于这种类，如果产生多个实例对象，就会出现各种异常状况；对于这种对象只要创建一次并且分配一次内存空间即可，所以这里也有个问题，对象所分配的内存空间的消耗，对于长期不使用的对象，这就产生资源浪费，所以利用单件模式，也可以按照需要来创建对象。<br/><br/><strong>定义</strong><br/><br/>单件模式确保一个类只有一个实例，并且提供一个全局访问点。 <br/><strong>类图</strong><br/><img src="http://www.94this.com.cn/myCode/singleton_class_1.gif" border="0" alt=""/><br/><br/>分析<br/>首先我们考虑到传统的编程语言如C#，单件模式中设置一个静态变量，可以这样表示：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">public sealed class Singleton<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;static Singleton instance = null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;//<br/>}<br/></div></div><br/>Singleton的构造函数设置为私有，防止Singleton多次实例化，这样就可以有以下的静态方法：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">public static Singleton Instance<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;get<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (instance == null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instance = new Singleton();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return instance;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>这样只有在第一次实例化的时候，才创建对象；通过静态方法，得到唯一实例；<br/><br/>这个是C#中最简单的单件模式写法。而Javascript作为弱类型语言，有着它独特的地方，现在我就来介绍Javascript单件模式的几种形式：<br/><br/>1. 最基本的单件模式<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var LoginUser = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;name : &#34;匿名用户&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;sex : &#34;保密&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;setName : function(name){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;setSex : function(sex){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.sex = sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getUserInfo : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;用户名：&#34; + this.name + &#34;；性别：&#34; +this.sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>这里定义了一个对象(LoginUser)，对象中包含了各种属性(name,sex)和方法(setName,setSex,getUserInfo)；<br/><br/>这样我新建一个HTML页面：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&lt;script type=&#34;text/javascript&#34;&gt;<br/>//<br/>window.onload = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;alert(LoginUser.getUserInfo());<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoginUser.setName(&#34;Leepy&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoginUser.setSex(&#34;男&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;//alert(LoginUser.getUserInfo());<br/>}<br/>function test() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;alert(LoginUser.getUserInfo());<br/>}<br/>&lt;/script&gt;<br/>&lt;input type=&#34;button&#34; value=&#34;test&#34; onclick=&#34;test();&#34; /&gt;<br/></div></div><br/>可以发现，界面初始化时弹出的警告框为“用户名：匿名用户；性别：保密”，通过setName和setSex方法之后，点击按钮后弹出的警告框为“ 用户名：Leepy；性别：男”，说明在不同的方法作用域下，LoginUser保持着修改后的状态，因此LoginUser在页面中就保持着单一的状态。<br/><br/>我想大家一定也听过prototype的JS框架了吧（<a href="http://www.prototypejs.org" target="_blank" rel="external">http://www.prototypejs.org</a>），最新版本为（<a href="http://www.prototypejs.org" target="_blank" rel="external">http://www.prototypejs.org</a>/assets/2008/9/29/prototype-1.6.0.3.js），实际上在它的文件中包含着很多这样类似的代码，比如从文件一开头就可以发现：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var Prototype = {<br/>&nbsp;&nbsp;Version: &#39;1.6.0.3&#39;, <br/><br/>&nbsp;&nbsp;Browser: {<br/>&nbsp;&nbsp;&nbsp;&nbsp;IE:&nbsp;&nbsp;&nbsp;&nbsp; !!(window.attachEvent &amp;&amp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;navigator.userAgent.indexOf(&#39;Opera&#39;) === -1),<br/>&nbsp;&nbsp;&nbsp;&nbsp;Opera:&nbsp;&nbsp;navigator.userAgent.indexOf(&#39;Opera&#39;) &gt; -1,<br/>&nbsp;&nbsp;&nbsp;&nbsp;WebKit: navigator.userAgent.indexOf(&#39;AppleWebKit/&#39;) &gt; -1,<br/>&nbsp;&nbsp;&nbsp;&nbsp;Gecko:&nbsp;&nbsp;navigator.userAgent.indexOf(&#39;Gecko&#39;) &gt; -1 &amp;&amp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;navigator.userAgent.indexOf(&#39;KHTML&#39;) === -1,<br/>&nbsp;&nbsp;&nbsp;&nbsp;MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)<br/>&nbsp;&nbsp;}, <br/><br/>&nbsp;&nbsp;BrowserFeatures: {<br/>&nbsp;&nbsp;&nbsp;&nbsp;XPath: !!document.evaluate,<br/>&nbsp;&nbsp;&nbsp;&nbsp;Sel&#101;ctorsAPI: !!document.querySel&#101;ctor,<br/>&nbsp;&nbsp;&nbsp;&nbsp;ElementExtensions: !!window.HTMLElement,<br/>&nbsp;&nbsp;&nbsp;&nbsp;SpecificElementExtensions:<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.cr&#101;ateElement(&#39;div&#39;)[&#39;__proto__&#39;] &amp;&amp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.cr&#101;ateElement(&#39;div&#39;)[&#39;__proto__&#39;] !==<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.cr&#101;ateElement(&#39;form&#39;)[&#39;__proto__&#39;]<br/>&nbsp;&nbsp;}, <br/><br/>&nbsp;&nbsp;ScriptFragment: &#39;&lt;script[^&gt;]*&gt;([\\S\\s]*?)&lt;\/script&gt;&#39;,<br/>&nbsp;&nbsp;JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/, <br/><br/>&nbsp;&nbsp;emptyFunction: function() { },<br/>&nbsp;&nbsp;K: function(x) { return x }<br/>};<br/>//以下是它的使用<br/>if (Prototype.Browser.MobileSafari)<br/>&nbsp;&nbsp;Prototype.BrowserFeatures.SpecificElementExtensions = false;<br/></div></div><br/>可以看出，Version、Browser、BrowserFeatures、ScriptFragment、JSONFilter作为Prototype对象的属性，而emptyFUnction、K作为Prototype对象的方法；因此它就是一个最基本的单件模式。<br/><br/>由于Javascript的语言特性，可以在后期动态添加，删除，修改属性：<br/><br/>如：LoginUser.age = 24;&nbsp;&nbsp;那么LoginUser对象便增加了age属性；而如：del&#101;te LoginUser.name; 那么LoginUser对象就删除了name属性；而如：LoginUser.name = &#34;cnblogs&#34;; 那么LoginUser对象的“私有”属性不需要通过setName的“公有”方法仍然能够做出修改。<br/><br/>因为根据设计模式原则：对扩展开放而对修改关闭，显然违背了该条准则。为了防止这种情况的发生，到时候会引入闭包的方式，稍后会说明。<br/><br/>2. 命名空间的单件模式<br/><br/>命名空间可以很好地划分 属性和方法 的归属，以及可以防止 属性和方法 被轻易的修改，通过访问各自的命名空间得到对应我们想要的 属性和方法。这里还是以上面的LoginUser为例：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var LoginUser = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;name : &#34;匿名用户&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;sex : &#34;保密&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;setName : function(name){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;setSex : function(sex){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.sex = sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getUserInfo : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;用户名：&#34; + this.name + &#34;；性别：&#34; +this.sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/>LoginUser.Mother = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;name : &#34;母亲姓名&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;career : &#34;职位&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;setName : function(name){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;setCareer : function(career){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.career = career;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getUserInfo : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return LoginUser.name + &#34;的母亲名字：&#34; + this.name + &#34;；职业：&#34; +this.career;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>从代码中看出，这里我把LoginUser作为“命名空间”，而LoginUser.Mother作为它的一个“全局变量”，这样做的好处可以防止 LoginUser的属性和方法被轻易地覆盖，通过LoginUser.××××，以致于LoginUser.××××.××××（如 LoginUser.Mother.Brother）来划分 属性和方法的归属，如LoginUser中的name属性和LoginUser.Mother中的name属性是区分开来的。<br/><br/>这样我新建一个HTML页面：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&lt;script type=&#34;text/javascript&#34;&gt; <br/>// <br/>window.onload = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoginUser.setName(&#34;Leepy&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoginUser.Mother.setName(&#34;admin&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoginUser.Mother.setCareer(&#34;农民&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;alert(LoginUser.Mother.getUserInfo());<br/>}<br/>&lt;/script&gt;<br/></div></div><br/>可以得到下面的弹出框：<br/><img src="http://www.94this.com.cn/myCode/singleton_class_2.gif" border="0" alt=""/><br/><br/>LoginUser和LoginUser.Mother的name属性已经区分开来了。<br/>在prototype.js文件中也用到命名空间的单件模式：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var Class = {<br/>&nbsp;&nbsp;cr&#101;ate: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var parent = null, properties = $A(arguments);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (Object.isFunction(properties[0]))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent = properties.shift();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;function klass() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.initialize.apply(this, arguments);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;Object.extend(klass, Class.Methods);<br/>&nbsp;&nbsp;&nbsp;&nbsp;klass.superclass = parent;<br/>&nbsp;&nbsp;&nbsp;&nbsp;klass.subclasses = [];<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;if (parent) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var subclass = function() { };<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;subclass.prototype = parent.prototype;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;klass.prototype = new subclass;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parent.subclasses.push(klass);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;for (var i = 0; i &lt; properties.length; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;klass.addMethods(properties[i]);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;if (!klass.prototype.initialize)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;klass.prototype.initialize = Prototype.emptyFunction;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;klass.prototype.constructor = klass;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;return klass;<br/>&nbsp;&nbsp;}<br/>};<br/><br/>Class.Methods = {<br/>&nbsp;&nbsp;addMethods: function(source) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var ancestor&nbsp;&nbsp; = this.superclass &amp;&amp; this.superclass.prototype;<br/>&nbsp;&nbsp;&nbsp;&nbsp;var properties = Object.keys(source);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;if (!Object.keys({ toString: true }).length)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;properties.push(&#34;toString&#34;, &#34;valueOf&#34;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;for (var i = 0, length = properties.length; i &lt; length; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var property = properties[i], value = source[property];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (ancestor &amp;&amp; Object.isFunction(value) &amp;&amp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value.argumentNames().first() == &#34;$super&#34;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var method = value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value = (function(m) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return function() { return ancestor[m].apply(this, arguments) };<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})(property).wrap(method);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value.valueOf = method.valueOf.bind(method);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value.toString = method.toString.bind(method);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.prototype[property] = value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;return this;<br/>&nbsp;&nbsp;}<br/>};<br/></div></div><br/>这里实际上Class.cr&#101;ate实现的是类的继承，具体这里我就不再阐述了，大家可以查看prototype官方的Api文档。<br/><br/>3. 闭包方式的单件模式<br/><br/>如果要得到真正意义上的“私有”成员，那么闭包方式是构造单件模式的一种选择。通过闭包的方式，只暴露一些可以公开的方法或者属性，而私有成员只在内部实现操作，而所有的属性和方法只需要实例化一次。现在开始继续看LoginUser的例子,闭包方式单件模式(上)对比基本单件模式(下)的例子：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">闭包方式单件模式<br/>var LoginUser = (function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;var _name = &#34;匿名用户&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;var _sex = &#34;保密&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setName : function(name){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setSex : function(sex){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sex = sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getUserInfo : function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;用户名：&#34; + _name + &#34;；性别：&#34; + _sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getName : function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;};<br/>})();<br/></div></div><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>对比基本单件模式&#160;&#160;&#160;&#160;<br/>var LoginUser = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;_name : &#34;匿名用户&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;_sex : &#34;保密&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;setName : function(name){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;setSex : function(sex){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._sex = sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getUserInfo : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;用户名：&#34; + this._name + &#34;；性别：&#34; +this._sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>可以发现，闭包方式将公共的方法放在return { ... }中，而属性_name和_sex做为参数传入return { ... }中；<br/><br/>现在两种方式都实现一下代码，测试一下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>window.onload = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoginUser.setName(&#34;Leepy&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;LoginUser.setSex(&#34;男&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;alert(LoginUser._name);<br/>}<br/></div></div><br/>可以得到闭包方式单件模式(左)对比第1条基本单件模式(右)如下两个结果：<br/><img src="http://www.94this.com.cn/myCode/singleton_class_3.gif" border="0" alt=""/><br/><br/>可以看出闭包方式的LoginUser无法得到_name的值，而基本方式的LoginUser可以得到_name的值；<br/><br/>这进一步说明了闭包方式的_name已经成为“私有”成员属性了。而如果要得到_name的值，只有通过公开方法或者公开属性来获得，如下：<br/>return { // 注意这里的“{”号不能够换行到下一行，不然浏览器提示错误<br/>&nbsp;&nbsp;&nbsp;&nbsp;getName : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return _name;<br/>&nbsp;&nbsp; }<br/>}<br/><br/>这样子，alert(LoginUser.getName()); 就可以显示正确的值了。<br/><br/><br/>继续看prototype.js文件中，其实也用到闭包方式的单件模式：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var Hash = Class.cr&#101;ate(Enumerable, (function() {<br/><br/>&nbsp;&nbsp;function toQueryPair(key, value) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (Object.isUndefined(value)) return key;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return key + &#39;=&#39; + encodeURIComponent(String.interpret(value));<br/>&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;return {<br/>&nbsp;&nbsp;&nbsp;&nbsp;initialize: function(object) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;_each: function(iterator) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (var key in this._object) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var value = this._object[key], pair = [key, value];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pair.key = key;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pair.value = value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iterator(pair);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;set: function(key, value) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this._object[key] = value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;get: function(key) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// simulating poorly supported hasOwnProperty<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this._object[key] !== Object.prototype[key])<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this._object[key];<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;unset: function(key) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var value = this._object[key];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;del&#101;te this._object[key];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;toObject: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Object.clone(this._object);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;keys: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.pluck(&#39;key&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;values: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.pluck(&#39;value&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;index: function(value) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var match = this.detect(function(pair) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return pair.value === value;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return match &amp;&amp; match.key;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;merge: function(object) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.clone().up&#100;ate(object);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;up&#100;ate: function(object) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new Hash(object).inject(this, function(result, pair) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.set(pair.key, pair.value);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return result;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;toQueryString: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.inject([], function(results, pair) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var key = encodeURIComponent(pair.key), values = pair.value;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (values &amp;&amp; typeof values == &#39;object&#39;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Object.isArray(values))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return results.concat(values.map(toQueryPair.curry(key)));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else results.push(toQueryPair(key, values));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return results;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}).join(&#39;&amp;&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;inspect: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#39;#&lt;Hash:{&#39; + this.map(function(pair) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return pair.map(Object.inspect).join(&#39;: &#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}).join(&#39;, &#39;) + &#39;}&gt;&#39;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;toJSON: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Object.toJSON(this.toObject());<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;clone: function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new Hash(this);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;}<br/>})());<br/></div></div><br/>Class.cr&#101;ate的第二个参数就是闭包方式的单件对象，这里的作用是将Hash对象继承于Enumerable类，并且包含了单件对象的公开方法如set,get,keys,values等等操作获取散列键值的方法。具体这里我就不再阐述了，大家可以查看prototype官方的Api文档。<br/><br/>4. 延迟加载的单件模式<br/>上面介绍的各种方式都是在建立对象的时候，对象内部的成员都已经加载完毕，如果对于资源占用多的脚本，在不需要的时候，这对于内存造成了极大的浪费，所以要考虑一种方式将成员实例化推迟到需要调用对象的时候，也就是叫做延迟加载。<br/>继续以LoginUser的例子作为演示：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var LoginUser = (function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;var uniqueInstance;<br/>&nbsp;&nbsp;&nbsp;&nbsp;var _name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;var _sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;function constructor(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_name = &#34;匿名用户&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sex = &#34;保密&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setName : function(name){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setSex : function(sex){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_sex = sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getUserInfo : function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;用户名：&#34; + _name + &#34;；性别：&#34; + _sex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getName : function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getInstance : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(uniqueInstance == null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;uniqueInstance = constructor();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return uniqueInstance;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>})();<br/></div></div><br/>可以看到，我这里添加了一个私有方法constructor()，并且由它来公开成员方法；<br/>再则，当第一次调用getInstance方法的时候，调用contructor方法，并且对于成员属性_name和_sex进行初始化，说明通过调用 getInstance方法才对属性进行初始化，平时不进行初始化，constructor()返回了一个uniqueInstance的对象，由 uniqueInstance对象负责该单件对象的公开方法的操作。<br/><br/>然后新建一个HTML页面：<br/>[/code]<br/>window.onload = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var user1 = LoginUser.getInstance();<br/>&nbsp;&nbsp;&nbsp;&nbsp;user1.setName(&#34;Leepy&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;user1.setSex(&#34;男&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;alert(user1.getUserInfo());//用户名：Leepy；性别：男<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;var user2 = LoginUser.getInstance();<br/>&nbsp;&nbsp;&nbsp;&nbsp;alert(user1 == user2); //user1和user2共享同一块内存空间，为true<br/>}<br/>[/code]<br/>只有通过LoginUser.getInstance()后，LoginUser才进行成员初始化，而方法返回的对象共享同一块的内存空间。这就是延迟加载单件模式的工作原理。<br/><br/>5. 其他<br/><br/>另外上次园里一位朋友(winter-cn)发我的一个单件设计模式的文章，觉得挺不错，它也是利用了“匿名”函数的特征构建了单件模式，我这里把代码贴出来一下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">&lt;script&gt;<br/>(function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;//instance declared<br/>&nbsp;&nbsp;&nbsp;&nbsp;//SingletonFactory Interface<br/>&nbsp;&nbsp;&nbsp;&nbsp;SingletonFactory = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getInstance : getInstance<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;//private classes<br/>&nbsp;&nbsp;&nbsp;&nbsp;function SingletonObject()<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SingletonObject.prototype.methodA = function()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&#39;methodA&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SingletonObject.prototype.methodB = function()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alert(&#39;methodB&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SingletonObject.instance = this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;//SingletonFactory implementions<br/>&nbsp;&nbsp;&nbsp;&nbsp;function getInstance()<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(SingletonObject.instance == null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new SingletonObject();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return SingletonObject.instance;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>})();<br/><br/>var instA = null;<br/>try<br/>{<br/>alert(&#34;试图通过new SingletonObject()构造实例！&#34;);<br/>instA = new SingletonObject();<br/>}<br/>catch(e){alert(&#34;SingletonObject构造函数不能从外部访问，系统抛出了异常！&#34;);}<br/><br/>instA = SingletonFactory.getInstance();&nbsp;&nbsp;//通过Factory上定义的静态方法获得<br/>var instB = SingletonFactory.getInstance();<br/>instA.methodA();<br/>instB.methodA();<br/><br/>alert(instA == instB); //成功<br/><br/>var instC = null;<br/>try<br/>{<br/>alert(&#34;试图通过new SingletonObject()构造实例！&#34;);<br/>instC = new SingletonObject();<br/>}<br/>catch(e){alert(&#34;SingletonObject构造函数不能从外部访问，系统抛出了异常！&#34;);}<br/>&lt;/script&gt;<br/></div></div><br/> <br/>总结<br/><br/>该篇文章用Javascript来设计单件模式的几种方式，在许多优秀的JS开源框架中，如 prototype，MicrosoftAjaxLibrary，jQuery，MooTools等等，都包含着大量单件模式的应用，所以单件模式在 Javascript中是很重要的一个模式。<br/><br/>附：<a target="_blank" href="http://www.94this.com.cn/myCode/Javascri&#112;tDPSingletonCode.rar" rel="external">源代码下载</a><br/><br/>本篇到此为止，谢谢大家阅读！<br/><br/><br/>参考文献：《Head First Design Pattern》<br/><br/>《Professional Javascript Design Patterns》 ]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/283.htm</link>
			<title><![CDATA[javascript的设计模式之六[命令模式(Command)]]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Tue,02 Jun 2009 22:17:29 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=283</guid>
		<description><![CDATA[<strong>概述</strong><br/><br/>在各种各样的行为实现中，行为请求者与行为实现者紧密耦合，当每增加一个行为实现的时候，行为请求者必须增加一个对行为的处理，这样就需要大量改动请求者的操作，显然这样不利于维护和扩展。为了让行为请求者和行为实现者解耦，可以将行为封装为一个命令对象，但需要处理行为时，只要请求者知道命令对象，它本身不需要知道命令对象都做些什么，命令对象负责执行 接收者 的真正实现，这样就达到二者之间松耦合的目的。<br/><br/><strong>定义</strong><br/><br/><strong>命令模式</strong>是将请求封装成对象，这可以让你使用不同请求、队列，或者日志请求来参数化其他对象。命令模式也可以支持撤销操作。<br/><br/><strong>类图</strong><br/><img src="http://www.94this.com.cn/myCode/command_class_1.gif" border="0" alt=""/><br/><br/><strong>实例分析</strong><br/><br/>现在开始利用命令模式来应用到一个在线编辑器的场景中，并且详细分析一下：<br/><br/>这里先给大家看下效果图（兼容多浏览器）：<br/><img src="http://www.94this.com.cn/myCode/command_2.gif" border="0" alt=""/><br/>这里我引用了<a target="_blank" href="http://www.94this.com.cn/article/282.htm" rel="external">第5篇－组合模式</a>的菜单例子进行改进；将命令模式和组合模式相结合的方式来阐述例子。<br/><br/>其中主菜单包括：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;* 文件（子菜单：新建、导出、退出）<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 编辑（子菜单：剪切、复制、粘贴、删除）<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 格式（子菜单：字体、字号、加粗、斜体、下划线、位置、编号、字体颜色）<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 插入（子菜单：插入链接、插入图片），操作（撤销、重做、切换HTML）<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 自定义格式（子菜单：格式1）<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 帮助（子菜单：关于作者）<br/><br/>编辑器的这些功能实际上很常用。最后点击“得到HTML值”的按钮，可以得到HTML的内容，这里就可以按照您的需要来存储编辑器内容；文章的最后我将附上源代码。<br/><br/> <br/><br/>1. 首先添加一个ICommand.js文件，其中定义一个Command接口：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var ICommand = new Interface(&#34;ICommand&#34;, [[&#34;execute&#34;]]);</div></div><br/><br/>其中execute作为Command执行的接口方法;<br/><br/>关于接口的定义，可以参考<a target="_blank" href="http://www.94this.com.cn/article/277.htm" rel="external">第1篇－面向对象基础以及接口和继承类的实现</a>。<br/><br/> <br/><br/>2. 添加一个ConcreteCommand.js文件，作为继承ICommand接口的所有具体实现类：<br/><br/>因为子菜单中的每个按钮都可作为一个具体实现类，那么我以“加粗”按钮为例，就可以得到：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>//加粗<br/>function onBoldCommand() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, ICommand);<br/>}<br/>onBoldCommand.prototype.execute = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var editor = window.frames[&#34;HtmlEditor&#34;];<br/>&nbsp;&nbsp;&nbsp;&nbsp;editor.document.execCommand(&#34;Bold&#34;, false, false);<br/>&nbsp;&nbsp;&nbsp;&nbsp;editor.focus();<br/>};<br/></div></div><br/>其中Interface.registerImplements(this, ICommand);说明它继承于ICommand接口，而execute方法作为基于接口方法的具体实现，这里实现了文档加粗功能；<br/><br/>3. 现在要创建“主菜单”和“子菜单”，Menu类和MenuItem类，注意这里“子菜单”也可能是Menu类，比如“格式”主菜单下的“位置”下面还包括下级菜单“居左对齐”，“居中对齐”，“居右对齐”等等，所以作为“叶子”结点的菜单就以MenuItem类来实现：<br/><br/> <br/>Menu类的实现如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Menu(text, title, href) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents = new Array();<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.text = text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.title = title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.href = href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, MenuComponent);<br/>} <br/><br/>Menu.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getElement : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents.length == 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(this.text + &#34;菜单下没有子菜单&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var liElement = document.cr&#101;ateElement(&#34;li&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;liElement.className = &#34;Menu-WithChildren&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;liElement.title = this.title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var anchor = document.cr&#101;ateElement(&#34;a&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;anchor.className = &#34;Menu-Link&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;anchor.href = this.href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;liElement.appendChild(anchor);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;anchor.innerHTML = this.text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var ulElement = document.cr&#101;ateElement(&#34;ul&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;liElement.appendChild(ulElement);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.menuComponents.length; i &lt; len; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ulElement.appendChild(this.menuComponents[i].getElement());<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return liElement;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;add : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.push(component);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;remove : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.menuComponents.length; i &lt; len; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents[i] == component)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.splice(i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;removeAt : function(index) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents.length &lt;= index)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.splice(index, 1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;索引操作数组超过上限&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>Menu继承于MenuComponent接口（var MenuComponent = new Interface(&#34;MenuComponent&#34;, [[&#34;getElement&#34;]]);），并且在上一篇组合模式讲过，它作为Composite复合元素。<br/>MenuItem的实现如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function MenuItem(text, title, href, command) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.text = text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.title = title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.href = href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.command = command;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, MenuComponent);<br/>} <br/><br/>MenuItem.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getElement : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var liElement = document.cr&#101;ateElement(&#34;li&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;liElement.className = &#34;Menu-Leaf&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;liElement.title = this.title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var anchor = document.cr&#101;ateElement(&#34;a&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;anchor.href = this.href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;liElement.appendChild(anchor);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;anchor.innerHTML = this.text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var command = this.command;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addEvent(anchor, &#34;click&#34;, function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;command.execute();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return liElement;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>其中参数command是作为传递进来的“命令对象”，比如前面的onBoldCommand的“加粗”命令对象，并且通过方法getElement()实现菜单按钮的点击触发达到命令对象的触发请求，而MenuItem不需要知道命令对象的具体实现；<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">addEvent(anchor, &#34;click&#34;, function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;command.execute();<br/>});</div></div><br/><br/>通过这句代码来添加点击事件从而执行命令对象的实现；<br/><br/>4. 既然有“主菜单”，“子菜单”，那么就需要有个“导航条”来“挂接”它们了，这里我添加了一个MenuBar对象，它作为一个初始化菜单显示和所有命令按钮行为实现方法的“容器”，代码如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var MenuBar = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;list : new Array(),<br/>&nbsp;&nbsp;&nbsp;&nbsp;add : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.list.push(component);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;show : function(container) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var ulElement = document.cr&#101;ateElement(&#34;ul&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ulElement.className = &#34;Menu&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.list.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ulElement.appendChild(this.list[i].getElement());<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(container).appendChild(ulElement);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>通过show方法进行初始化菜单显示和所有命令按钮行为的实现方法；<br/><br/>5. 现在利用命令模式来进行在线编辑器的实现，新建HTML页面，在window.onload方法中实现：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var file_menu = new Menu(&#34;文件&#34;, &#34;文件&#34;, &#34;#&#34;);<br/>file_menu.add(new MenuItem(&#34;新建&#34;, &#34;新建&#34;, &#34;#&#34;, new onNewCommand()));<br/>file_menu.add(new MenuItem(&#34;导出&#34;, &#34;导出&#34;, &#34;#&#34;, new onExportCommand()));<br/>file_menu.add(new MenuItem(&#34;退出&#34;, &#34;退出&#34;, &#34;#&#34;, new onExitCommand()));<br/>var edit_menu = new Menu(&#34;编辑&#34;, &#34;编辑&#34;, &#34;#&#34;);<br/>edit_menu.add(new MenuItem(&#34;剪切&#34;, &#34;剪切&#34;, &#34;#&#34;, new onCutCommand()));<br/>edit_menu.add(new MenuItem(&#34;复制&#34;, &#34;复制&#34;, &#34;#&#34;, new onCopyCommand()));<br/>edit_menu.add(new MenuItem(&#34;粘贴&#34;, &#34;粘贴&#34;, &#34;#&#34;, new onPasteCommand()));<br/>edit_menu.add(new MenuItem(&#34;删除&#34;, &#34;删除&#34;, &#34;#&#34;, new onDel&#101;teCommand())); <br/><br/>var format_menu = new Menu(&#34;格式&#34;, &#34;格式&#34;, &#34;#&#34;);<br/>format_menu.add(new MenuItem(&#34;字体&#34;, &#34;字体&#34;, &#34;#&#34;, new onFontFaceCommand()));<br/>format_menu.add(new MenuItem(&#34;字号&#34;, &#34;字号&#34;, &#34;#&#34;, new onFontSizeCommand()));<br/>format_menu.add(new MenuItem(&#34;加粗&#34;, &#34;加粗&#34;, &#34;#&#34;, new onBoldCommand()));<br/>format_menu.add(new MenuItem(&#34;斜体&#34;, &#34;斜体&#34;, &#34;#&#34;, new onItalicCommand()));<br/>format_menu.add(new MenuItem(&#34;下划线&#34;, &#34;下划线&#34;, &#34;#&#34;, new onUnderlineCommand()));<br/>var format_menu_1 = new Menu(&#34;位置&#34;, &#34;位置&#34;, &#34;#&#34;);<br/>format_menu_1.add(new MenuItem(&#34;居左对齐&#34;, &#34;居左对齐&#34;, &#34;#&#34;, new onLeftCommand()));<br/>format_menu_1.add(new MenuItem(&#34;居中对齐&#34;, &#34;居中对齐&#34;, &#34;#&#34;, new onCenterCommand()));<br/>format_menu_1.add(new MenuItem(&#34;居右对齐&#34;, &#34;居右对齐&#34;, &#34;#&#34;, new onRightCommand()));<br/>format_menu_1.add(new MenuItem(&#34;减少缩进&#34;, &#34;减少缩进&#34;, &#34;#&#34;, new onOutdentCommand()));<br/>format_menu_1.add(new MenuItem(&#34;增加缩进&#34;, &#34;增加缩进&#34;, &#34;#&#34;, new onIndentCommand()));<br/>format_menu.add(format_menu_1);<br/>var format_menu_2 = new Menu(&#34;编号&#34;, &#34;编号&#34;, &#34;#&#34;);<br/>format_menu_2.add(new MenuItem(&#34;数字编号&#34;, &#34;数字编号&#34;, &#34;#&#34;, new onOrderedCommand()));<br/>format_menu_2.add(new MenuItem(&#34;项目编号&#34;, &#34;项目编号&#34;, &#34;#&#34;, new onUnorderedCommand()));<br/>format_menu.add(format_menu_2);<br/>var format_menu_3 = new Menu(&#34;字体颜色&#34;, &#34;字体颜色&#34;, &#34;#&#34;);<br/>format_menu_3.add(new MenuItem(&#34;前景颜色&#34;, &#34;前景颜色&#34;, &#34;#&#34;, new onForeColorCommand()));<br/>format_menu_3.add(new MenuItem(&#34;背景颜色&#34;, &#34;背景颜色&#34;, &#34;#&#34;, new onBackColorCommand()));<br/>format_menu.add(format_menu_3); <br/><br/>var ins&#101;rt_menu = new Menu(&#34;插入&#34;, &#34;插入&#34;, &#34;#&#34;);<br/>ins&#101;rt_menu.add(new MenuItem(&#34;插入链接&#34;, &#34;插入链接&#34;, &#34;#&#34;, new onLinkCommand()));<br/>ins&#101;rt_menu.add(new MenuItem(&#34;插入图片&#34;, &#34;插入图片&#34;, &#34;#&#34;, new onImageCommand())); <br/><br/>var opr_menu = new Menu(&#34;操作&#34;, &#34;操作&#34;, &#34;#&#34;);<br/>opr_menu.add(new MenuItem(&#34;撤销&#34;, &#34;撤销&#34;, &#34;#&#34;, new onUndoCommand()));<br/>opr_menu.add(new MenuItem(&#34;重做&#34;, &#34;重做&#34;, &#34;#&#34;, new onRedoCommand()));<br/>opr_menu.add(new MenuItem(&#34;切换HTML&#34;, &#34;切换HTML&#34;, &#34;#&#34;, new onToHtmlCommand())); <br/><br/>var custom_menu = new Menu(&#34;自定义格式&#34;, &#34;自定义格式&#34;, &#34;#&#34;);<br/>custom_menu.add(new MenuItem(&#34;格式1&#34;, &#34;加粗＋斜体＋下划线&#34;, &#34;#&#34;, new onMacro1Command(new onBoldCommand(), new onItalicCommand(), new onUnderlineCommand()))); <br/><br/>var help_menu = new Menu(&#34;帮助&#34;, &#34;帮助&#34;, &#34;#&#34;);<br/>help_menu.add(new MenuItem(&#34;关于作者&#34;, &#34;关于作者&#34;, &#34;#&#34;, new onAuthorCommand())); <br/><br/>MenuBar.add(file_menu);<br/>MenuBar.add(edit_menu);<br/>MenuBar.add(format_menu);<br/>MenuBar.add(ins&#101;rt_menu);<br/>MenuBar.add(opr_menu);<br/>MenuBar.add(custom_menu); <br/>MenuBar.add(help_menu); <br/><br/>MenuBar.show(&#34;main_container&#34;);<br/></div></div><br/>各个命令对象作为命令参数传递给对应的子菜单项对象中，其中我们发现有个onMacro1Command的命令对象，它里面包含一系列的其他单命令对象，这个菜单按钮属于“自定义格式”。顾名思义，这里执行一个新的命令，它包括一连串的单命令，“加粗＋斜体＋下划线”，onMacro1Command类实现如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">function onMacro1Command() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.commands = new Array();<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = arguments.length; i &lt; len; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.commands.push(arguments[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, ICommand);<br/>}<br/>onMacro1Command.prototype.execute = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.commands.length; i &lt; len; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.commands[i].execute();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>};<br/></div></div><br/>这里通过一个commands数组存储这一系列的命令对象，当onMacro1Command对象执行execute方法时，就一次性地执行数组中的所有命令对象；<br/><br/>6. 还有其他一些JS函数介绍下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function addEvent(target, event_type, handler) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;if (target.addEventListener) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;target.addEventListener(event_type, handler, false);<br/>&nbsp;&nbsp;&nbsp;&nbsp;else if (target.attachEvent)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;target.attachEvent(&#34;on&#34; + event_type, handler);<br/>&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;target[&#34;on&#34; + event_type] = handler;<br/>}<br/>//弹出DIV层<br/>function showDiver(str, width, height) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var iWidth = width;<br/>&nbsp;&nbsp;&nbsp;&nbsp;var iHeight = height;<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;diver&#34;).style.width = iWidth + &#34;px&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;diver&#34;).style.height = iHeight + &#34;px&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;diver&#34;).style.left = (document.body.clientWidth - iWidth)/2 + &#34;px&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;diver&#34;).style.top = (document.body.clientHeight - iHeight)/2 + &#34;px&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;diver&#34;).style.display = &#34;inline&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;divMore&#34;).innerHTML = str;<br/>}<br/>//关闭DIV层<br/>function closeDiver() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;diver&#34;).style.display = &#34;none&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(&#34;divMore&#34;).innerHTML = &#34;&#34;;<br/>}<br/></div></div><br/>其中addEvent方法为了兼容各个浏览器的绑定事件的实现。<br/><br/>7. 至于ConcreteCommand各种命令类的实现，请下载源代码自己查看研究吧，这里不进行讲述了。<br/><br/> <br/>附：<a target="_blank" href="http://www.94this.com.cn/myCode/Javascri&#112;tDPCommandCode.rar" rel="external">源代码下载</a><br/><br/>总结<br/><br/>该篇文章用Javascript设计命令模式的思路，实现一个简单的在线编辑器。<br/><br/>本篇到此为止，谢谢大家阅读<br/><br/>参考文献：《Head First Design Pattern》<br/><br/>《Professional Javascript Design Patterns》 ]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/282.htm</link>
			<title><![CDATA[javascript的设计模式之五[组合模式(Composite)]]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Mon,01 Jun 2009 20:57:42 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=282</guid>
		<description><![CDATA[<strong>概述</strong><br/><br/>它又是部分－整体的模式，元素有两种形式，一种是简单元素，一种是复杂元素，其中复杂元素是简单元素的组成，所以客户程序要操作复杂元素时，有时候它并不想了解内部包括哪些简单元素，但是又想能够保持简单元素的简易操作性，于是，就有了组合模式，它可以抽象成一个树状结构，其中简单元素为叶子结点，而复杂元素为非叶子结点。<br/><br/><strong>定义</strong><br/><br/>组合模式允许你将对象组合成树形结构以表示“整体/部分”的层次结构。组合能让客户以一致的方式处理个别对象以及对象组合。<br/><br/><strong>类图</strong><br/><br/><img src="http://www.94this.com.cn/myCode/composite_class_1.gif" border="0" alt=""/><br/><br/><br/><strong>实例分析</strong><br/><br/>这里我给出一个利用组合模式设计的菜单导航：<br/><br/>先看下效果图：<br/><img src="http://www.94this.com.cn/myCode/composite_2.gif" border="0" alt=""/><br/><br/>现在开始分析通过组合模式如何实现它：<br/><br/>1. 引用InterfaceAndClass.js文件，作为接口的构造和类的继承，这个不多说了，详细请看前面的文章；<br/><br/>2. 添加MenuComponent.js文件，作为Component接口或者抽象类，这里我用了接口的形式：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var MenuComponent = new Interface(&#34;MenuComponent&#34;, [[&#34;getValue&#34;]]);</div></div><br/><br/>3. 添加MenuItem.js文件，作为Leaf简单元素，这里指菜单的叶子结点：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function MenuItem(text, title, href) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.text = text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.title = title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.href = href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, MenuComponent);<br/>}<br/><br/>MenuItem.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getValue : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>其中text为菜单上显示的文本，title为提示文本符，href为链接导向；并且让它继承MenuComponent接口；<br/><br/>4. 添加Menu.js文件，作为Composite复合元素，它是由一系列的Leaf简单元素组成的：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Menu(text, title, href) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents = new Array();<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.text = text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.title = title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.href = href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, MenuComponent);<br/>}<br/><br/>Menu.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getValue : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;add : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.push(component);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;remove : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.menuComponents.length; i &lt; len; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents[i] == component)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.splice(i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;removeAt : function(index) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents.length &lt;= index)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.splice(index, 1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;索引操作数组超过上限&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>它继承MenuAComponent接口，因此它和MenuItem使用同一个接口，这样可以统一简单元素和复杂元素的方法调用，add方法用来添加component类，这里的component可以是Menu，也可以是MenuItem；remove方法用来删除指定的component 类；removeAt方法用过索引删除相应的component类；getValue方法取得菜单数据；<br/><br/>让我们先从实例上得到一个树状图： <br/><img src="http://www.94this.com.cn/myCode/composite_3.gif" border="0" alt=""/><br/>从图上可以看出，实际上菜单1，菜单2-1，菜单2-2-1，菜单2-2-2，菜单2-3，菜单3-1，菜单4都是属于Leaf，即MenuItem类；<br/><br/>菜单2，菜单2-2，菜单3都属于Composite，即Menu类；<br/><br/>这样Menu类的GetValue方法可以通过遍历它的子结点数组，得到所有子结点菜单数据；<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>for(var i = 0, len = this.menuComponents.length; i &lt; len; i++)<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;str += this.menuComponents[i].getValue();<br/>}<br/></div></div><br/>其中this.menuComponents[i].getValue()可以是Menu类的getValue方法，也可以是MenuItem类的getValue方法；<br/><br/>这样就可以完成了所有结点的遍历。<br/><br/>然后给出MenuItem.js和Menu.js的完整代码如下：<br/>MenuItem.js<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function MenuItem(text, title, href) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.text = text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.title = title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.href = href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, MenuComponent);<br/>}<br/><br/>MenuItem.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getValue : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var str = &#34;&lt;li class=\&#34;Menu-Leaf\&#34; title=\&#34;&#34; + this.title + &#34;\&#34;&gt;&lt;a href=\&#34;&#34; + this.href + &#34;\&#34;&gt;&#34; + this.text + &#34;&lt;/a&gt;&lt;/li&gt;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return str;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}</div></div><br/>Menu.js<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Menu(text, title, href) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents = new Array();<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.text = text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.title = title;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.href = href;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, MenuComponent);<br/>}<br/><br/>Menu.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getValue : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents.length == 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(this.text + &#34;菜单下没有子菜单&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var str = &#34;&lt;li class=\&#34;Menu-WithChildren\&#34; title=\&#34;&#34; + this.title + &#34;\&#34;&gt;&lt;a class=\&#34;Menu-Link\&#34; href=\&#34;&#34; + this.href + &#34;\&#34;&gt;&#34; + this.text + &#34;&lt;/a&gt;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str += &#34;&lt;ul&gt;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.menuComponents.length; i &lt; len; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str += this.menuComponents[i].getValue();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str += &#34;&lt;/ul&gt;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return str;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;add : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.push(component);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;remove : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.menuComponents.length; i &lt; len; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents[i] == component)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.splice(i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;removeAt : function(index) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(this.menuComponents.length &lt;= index)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.menuComponents.splice(index, 1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;索引操作数组超过上限&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div> <br/>5. 接着添加一个Menu操作类MenuOpr：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var MenuOpr = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;list : new Array(),<br/>&nbsp;&nbsp;&nbsp;&nbsp;add : function(component) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.list.push(component);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;print : function(container) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var str = &#34;&lt;ul class=\&#34;Menu\&#34;&gt;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = this.list.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;str += this.list[i].getValue();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.getElementById(container).innerHTML = str + &#34;&lt;/ul&gt;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>6. 最后利用组合模式编写调用代码：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var menu1 = new MenuItem(&#34;菜单1&#34;,&#34;菜单1&#34;,&#34;#&#34;);<br/><br/>var menu2 = new Menu(&#34;菜单2&#34;,&#34;菜单2&#34;,&#34;#&#34;);<br/>var menu2_1 = new MenuItem(&#34;菜单2-1&#34;, &#34;菜单2-1&#34;, &#34;#&#34;);<br/>var menu2_2 = new Menu(&#34;菜单2-2&#34;, &#34;菜单2-2&#34;, &#34;#&#34;);<br/>var menu2_2_1 = new MenuItem(&#34;菜单2-2-1&#34;, &#34;菜单2-2-1&#34;, &#34;#&#34;);<br/>var menu2_2_2 = new MenuItem(&#34;菜单2-2-2&#34;, &#34;菜单2-2-2&#34;, &#34;#&#34;);<br/>var menu2_3 = new MenuItem(&#34;菜单2-3&#34;,&#34;菜单2-3&#34;,&#34;#&#34;);<br/>menu2.add(menu2_1);<br/>menu2.add(menu2_2);<br/>menu2_2.add(menu2_2_1);<br/>menu2_2.add(menu2_2_2);<br/>menu2.add(menu2_3);<br/><br/>var menu3 = new Menu(&#34;菜单3&#34;,&#34;菜单3&#34;,&#34;#&#34;);<br/>var menu3_1 = new MenuItem(&#34;菜单3-1&#34;,&#34;菜单3-1&#34;,&#34;#&#34;);<br/>menu3.add(menu3_1);<br/><br/>var menu4 = new MenuItem(&#34;菜单4&#34;,&#34;菜单4&#34;,&#34;#&#34;);<br/><br/>MenuOpr.add(menu1);<br/>MenuOpr.add(menu2);<br/>MenuOpr.add(menu3);<br/>MenuOpr.add(menu4);<br/><br/>MenuOpr.print(&#34;main_container&#34;);<br/></div></div><br/>main_container为一个div层的id，这里代码就不多说了，一看就看得懂的。<br/><br/>当然实现这个菜单还是有不少方法的，而我这肯定不是最优的，这里我只是提供一个利用组合模式的思路而已；<br/><br/>如果按照常规，你可以把MenuItem都整合到Menu上，即MenuItem都改为Menu，这样的代码，你是不是更喜欢点呢？<br/><br/>这个就留给大家自己研究吧！<br/><br/>最后，说下由于文中实例的菜单样式采用li:hover的方式来弹出下级菜单，由于这个方式对于IE7以下版本是无效的，所以这里引用了<a target="_blank" href="http://www.codeplex.com/cssfriendly" rel="external">cssfriendly</a>开源项目中的两个JS文件，MenuAdapter.js和AdapterUtils.js，所以把它们放进项目中引用进来，这样该菜单就兼容了IE7以下版本的浏览器。<br/><br/>附：<a target="_blank" href="http://www.94this.com.cn/myCode/Javascri&#112;tDPCompositeCode.rar" rel="external">源代码下载</a><br/><br/>总结<br/><br/>该篇文章用Javascript设计组合模式的思路，实现一个菜单实例。<br/><br/>本篇到此为止，谢谢大家阅读！<br/><br/> <br/><br/>参考文献：《Head First Design Pattern》]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/280.htm</link>
			<title><![CDATA[javascript的设计模式之四[装饰者模式(Decorator) ]]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Tue,26 May 2009 23:22:29 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=280</guid>
		<description><![CDATA[<strong>概述</strong><br/><br/>在软件开发中，经常因为需求变动而需要扩展功能，想到的可能是继承类的方式进行扩展（还可以是组合方式（这个别篇另谈）），但是随着功能越来越多，子类也会越来越多，这样很不利用维护；而且需求的变动还导致部分功能也许不再需要，所以能够按需求来动态地扩展所需要的功能，是很好的解决方式；这样，装饰者模式应油而生，它动态地解决了功能扩展的问题<br/><br/>这里借用《Head First Design Pattern》归纳的五点：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;* 装饰者和被装饰者对象有相同的超类型<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 你可以用一个或是多个装饰者包装一个对象<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 既然装饰者和被装饰对象有相同的超类型，所以在任何需要原始对象（被包装）的场合，可以用装饰过的对象代替它<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 装饰者可以在所委托被装饰者的行为之前与/或之后，加上自己的行为，以达到特定的目的<br/>&nbsp;&nbsp;&nbsp;&nbsp;* 对象可以在任何时候被装饰，所以可以在运行是动态地、不限量地用你喜欢的装饰者来装饰对象<br/><br/><strong>定义<br/><br/>[b]装饰者模式</strong>是动态地将责任附加到对象上。若要扩展功能，装饰者提供了比继承更有弹性的替代方案。<br/><br/><strong>类图</strong><br/><img src="http://www.94this.com.cn/myCode/decorator_class_1.gif" border="0" alt=""/><br/><br/>原理分析<br/><br/>现在结合Javascript，开始介绍Javascript装饰者模式，这里我举个多功能复印机的例子来说明：<br/><br/> <br/><br/>1. 首先最开始我定义一个复印机接口，它会什么呢？它有说明书，要插电，可查看时间，可修理，可进行复印，有价格<br/><br/>那就可以这样子得到：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var IManifdder = new Interface(&#34;IManifdder&#34;, [[&#34;getDescription&#34;],[&#34;electrify&#34;],[&#34;watch&#34;],[&#34;repair&#34;],[&#34;duplicate&#34;],[&#34;getPrice&#34;]]);</div></div><br/><br/><br/><br/>2. 然后定义一个继承于该复印机接口的类Manifdder：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Manifdder() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IManifdder);<br/>}<br/>Manifdder.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getDescription : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;electrify : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;watch : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;repair : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;duplicate : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//打印操作<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getPrice : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 500.0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>};<br/></div></div><br/>3. 接着定义一个继承复印机接口的装饰者抽象类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function ManifdderDecorator(manifdder) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.manifdder = manifdder;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IManifdder);<br/>}<br/>ManifdderDecorator.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getDescription : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getDescription();<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;electrify : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.electrify();<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;watch : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.watch();<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;repair : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.repair();<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;duplicate : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.duplicate();<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getPrice : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getPrice();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>};<br/></div></div><br/>每个装饰者都有一个变量来保存IManifdder的引用，现在来实现它的具体类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>//中国制造<br/>function MakeInChinaDecorator(manifdder) { <br/>&nbsp;&nbsp;&nbsp;&nbsp;ManifdderDecorator.call(this,manifdder);<br/>}<br/>inheritClass(MakeInChinaDecorator, ManifdderDecorator);<br/>MakeInChinaDecorator.prototype.electrify = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.electrify() + &#34;. 中国标准电压为220V.&#34;;<br/>};<br/>MakeInChinaDecorator.prototype.getPrice = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getPrice() + 100.0;<br/>};<br/><br/>//日本制造<br/>function MakeInJapanDecorator(manifdder) { <br/>&nbsp;&nbsp;&nbsp;&nbsp;ManifdderDecorator.call(this,manifdder);<br/>}<br/>inheritClass(MakeInJapanDecorator);<br/>MakeInJapanDecorator.prototype.electrify = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.electrify() + &#34;.日本标准电压为110V.&#34;;<br/>};<br/>MakeInJapanDecorator.prototype.getPrice = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getPrice() + 200.0;<br/>};<br/></div></div><br/>其中它覆盖了抽象类中的electrify和getPrice方法；<br/><br/>现在执行它们：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var manifdder = new Manifdder();<br/>alert(manifdder.getPrice());&nbsp;&nbsp;// 得到500.0<br/>manifdder = new MakeInChinaManifdder(manifdder);<br/>alert(manifdder.getPrice()); // 得到600.0<br/></div></div><br/>如果再需要添加一个具体装饰类MakeInAmericaDecorator，只要再定义一个继承抽象类的子类即可；<br/><br/><br/>3. 什么叫做被装饰者方法之前或者之后，添加行为呢？接着看下下面的例子：<br/><br/>在方法之后添加行为：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function MakeInChinaDecorator(manifdder) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;//<br/>}<br/>inheritClass(MakeInChinaDecorator, ManifdderDecorator);<br/>//<br/>MakeInChinaDecorator.prototype.getPrice = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getPrice() + 100.0;<br/>};<br/></div></div><br/>实际上刚才上面的那个例子，就是方法之后添加行为的方式，当实例化MakeInChinaDecorator对象的时候，它的装饰目的是为了价格上的差异,当调用getPrice（方法之后）的时候，价格上才得以体现出来，在原来价格的基础上加上100.0。<br/><br/>而在方法之前添加行为，我这里在增加一个复印机的颜色装饰类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function ColorDecorator(manifdder, color) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;ManifdderDecorator.call(this,manifdder);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.color = color;<br/>}<br/>inheritClass(ColorDecorator, ManifdderDecorator);<br/>ColorDecorator.prototype.getDescription = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getDescription() + &#34;: &#34; + &#34;它的颜色是&#34; + this.color;<br/>};<br/></div></div><br/>当实例化ColorDecorator对象的时候，它的装饰目的已经在构造函数中得到颜色上的体现，因此它是在getDescription()方法调用之前就得到体现了。<br/><br/>现在执行它：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>manifdder = new ColorDecorator(manifdder, &#34;白色&#34;);<br/>alert(manifdder.getDescription()); //得到“它的颜色是白色”<br/></div></div><br/><br/>4. 现在我要实现多功能复印机，还具有打印，扫描，传真功能，那么开始添加它们的装饰类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function PrintDecorator(manifdder) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;ManifdderDecorator.call(this,manifdder);<br/>}<br/>inheritClass(PrintDecorator, ManifdderDecorator);<br/>PrintDecorator.prototype.getDescription = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getDescription() + &#34;: &#34; + &#34;它具有打印功能. &#34;;<br/>};<br/>PrintDecorator.prototype.getPrice = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.manifdder.getPrice() + 220.0;<br/>};<br/>PrintDecorator.prototype.print = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return &#34;Print!&#34;;<br/>};<br/></div></div><br/>现在执行它：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var manifdder = new Manifdder();<br/>manifdder = new PrintDecorator(manifdder);<br/>alert(manifdder.print()); //得到“Print!”<br/></div></div><br/>从结果可以看出，manifdder引用的对象具有方法print；<br/><br/>如果我继续装饰一个MakeInChina：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var manifdder = new Manifdder();<br/>manifdder = new PrintDecorator(manifdder);<br/>manifdder = new MakeInChinaDecorator(manifdder);<br/>alert(manifdder.print()); //得到“manifdder.print is not a function”<br/></div></div><br/>从结果可以看出，print已经找不到了。<br/><br/>这说明MakeInChinaDecorator装饰manifdder的时候，它的父类ManifdderDecorator不包含print方法，所以自然就调用不到；<br/><br/>这个问题要如何解决呢？我们看到ManifdderDecorator的构造函数传进来一个manifdder 的引用，通过它的引用我们可以得到它可能含有的新方法，比如print，通过和接口方法的比较，将新进的方法，动态添加进 ManifdderDecorator中，于是我们修改ManifdderDecorator抽象类，如下所示：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">function ManifdderDecorator(manifdder) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.manifdder = manifdder;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;this.interface = IManifdder;<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var key in this.manifdder) <br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(typeof this.manifdder[key] !== &#34;function&#34;)&nbsp;&nbsp;//判断是否为方法类<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var i;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i = 0, len = this.interface.methods.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(key == this.interface.methods[i][0]) { //通过遍历比较在接口类中是否包含此方法，如果包含返回下一个<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(i &lt; this.interface.methods.length)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var decorator = this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//采用匿名函数调用方式来定义新方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(function(methodName) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decorator[methodName] = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return decorator.manifdder[methodName]();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})(key);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IManifdder);<br/>};<br/>ManifdderDecorator.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;//<br/>};<br/></div></div><br/>这样，如果在装饰类中定义了新方法，它的抽象类就会把该新方法动态定义出来，这样保证方法调用上的正确；<br/><br/>然后再执行刚才的代码：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var manifdder = new Manifdder();<br/>manifdder = new PrintDecorator(manifdder);<br/>manifdder = new MakeInChinaDecorator(manifdder);<br/>alert(manifdder.print()); //得到“Print!”<br/></div></div><br/>成功调用了！<br/><br/>其他扫描，传真功能，和打印功能类似，创建ScanDecorator和FaxDecorator，这里不在多说了。<br/><br/><br/><strong>实例分析</strong><br/><br/>今天要介绍的场景是个 个人服装秀（类似于QQ秀）的网页范例，可以更换头像，上衣，腰裤，背景等。<br/><br/>效果图先让大家瞧瞧：<br/><img src="http://www.94this.com.cn/mycode/decorator_display1.gif" border="0" alt=""/><br/><img src="http://www.94this.com.cn/mycode/decorator_display2.gif" border="0" alt=""/><br/><br/>这里介绍几个核心代码：<br/><br/>1. 添加IPerson.js的IPerson接口类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var IPerson = new Interface(&#34;IPerson&#34;, [[&#34;getData&#34;]]);</div></div><br/><br/>2. 添加PersonDecorator.js的装饰者抽象类：<br/>PersonDecorator.js<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function PersonDecorator(person) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.person = person;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.interface = IPerson;<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var key in this.person) <br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(typeof this.person[key] !== &#34;function&#34;) //判断是否为方法类<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var i;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(i = 0, len = this.interface.methods.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(key == this.interface.methods[i][0]) { //通过遍历比较在接口类中是否包含此方法，如果包含返回下一个<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(i &lt; this.interface.methods.length)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var decorator = this;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//采用匿名函数调用方式来定义新方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(function(methodName) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;decorator[methodName] = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return decorator.person[methodName]();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;})(key);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IPerson);<br/>}<br/>PersonDecorator.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getData : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;抽象方法，不能调用!&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>3. 添加ConcreteDecorator.js的具体装饰者：<br/>ConcreteDecorator.js<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>// 头像装饰者<br/>function HeadDecorator(person, model) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;PersonDecorator.call(this, person);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.model = model;<br/>}<br/>inheritClass(HeadDecorator, PersonDecorator);<br/>HeadDecorator.prototype.getData = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var index = this.person.head.lastIndexOf(&#34;_&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(index != -1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.person.head = this.person.head.slice(0, index);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.person.head = this.person.head + &#34;_&#34; + this.model;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.person;<br/>};<br/><br/>// 上衣装饰者<br/>function BodyDecorator(person, model) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;PersonDecorator.call(this, person);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.model = model;<br/>}<br/>inheritClass(BodyDecorator, PersonDecorator);<br/>BodyDecorator.prototype.getData = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var index = this.person.body.lastIndexOf(&#34;_&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(index != -1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.person.body = this.person.body.slice(0, index);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.person.body = this.person.body + &#34;_&#34; + this.model;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.person;<br/>};<br/><br/>// 腰裤装饰者<br/>function FootDecorator(person, model) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;PersonDecorator.call(this, person);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.model = model;<br/>}<br/>inheritClass(FootDecorator, PersonDecorator);<br/>FootDecorator.prototype.getData = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var index = this.person.foot.lastIndexOf(&#34;_&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(index != -1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.person.foot = this.person.foot.slice(0, index);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.person.foot = this.person.foot + &#34;_&#34; + this.model;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.person;<br/>};<br/><br/>// 背景装饰者<br/>function BackgroundDecorator(person, model) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;PersonDecorator.call(this, person);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.model = model;<br/>}<br/>inheritClass(BackgroundDecorator, PersonDecorator);<br/>BackgroundDecorator.prototype.getData = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.person.background = &#34;bg&#34; + this.model;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.person;<br/>};<br/></div></div><br/>4. 添加PersonOpr.js，创建操作类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var PersonOpr = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;display : function(person) { //显示个人秀照片<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $(&#34;#imgHead&#34;).attr(&#34;src&#34;,&#34;images/&#34; + person.head + &#34;.gif&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#imgBody&#34;).attr(&#34;src&#34;,&#34;images/&#34; + person.body + &#34;.gif&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#imgFoot&#34;).attr(&#34;src&#34;,&#34;images/&#34; + person.foot + &#34;.gif&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#divBg&#34;).css(&#34;background-image&#34;, &#34;url(images/&#34; + person.background + &#34;.gif)&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;init : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//初始化皮肤列表<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//...<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/> <br/><br/>至此，装饰者模式的思路已经应用在该个人服装秀中了。<br/><br/><strong>总结</strong><br/><br/>该篇文章用Javascript设计装饰者模式的思路，重点从原理中分析，最后实现一个类似于QQ秀的应用网站。]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/279.htm</link>
			<title><![CDATA[javascript的设计模式之三[抽象工厂以及工厂方法模式(Factory) ]]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Thu,21 May 2009 22:34:56 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=279</guid>
		<description><![CDATA[<strong>概述</strong><br/><br/>抽象工厂模式广泛应用于因为需求变动导致一些相似对象的创建工作，拿我们做项目最熟悉的多版本数据库，根据数据库的不同，有可能有 SQLServer，Access，Oracle，MySQL版本等等的数据库，这样我们就能运用工厂模式，把各个数据库中相似的功能操作封装到它们各自的对象模型中，通过工厂对象统一创建各个对象实例，是客户程序和这些具体对象实现了松耦合；而工厂方法模式主要是针对某个对象的需求变更，但是这个对象不会随着它的变动而导致它所在的业务流程中的变动，它具有高聚合的能力，因此它的外部接口是很稳定的；<br/><br/><strong>定义</strong><br/><br/><strong>抽象工厂模式</strong>是每个抽象产品派生多个具体产品类，每个抽象工厂派生多个具体工厂类，每个具体工厂负责多个（一系列）具体产品的实例创建。<br/><br/><strong>工厂方法模式</strong>是每个抽象产品派生多个具体产品类，每个抽象工厂类派生多个具体工厂类，每个具体工厂类负责一个具体产品的实例创建。<br/><br/><strong>类图</strong><br/><br/><strong>抽象工厂模式类图</strong><br/><br/><img src="http://www.94this.com.cn/myCode/abstract_factory_class_1.gif" border="0" alt=""/><br/><br/><strong>工厂方法模式类图</strong><br/><br/><img src="http://www.94this.com.cn/myCode/abstract_factory_class_2.gif" border="0" alt=""/><br/><br/><br/><strong>实例分析</strong><br/><br/>在开始工厂模式之前，有必要先介绍下简单工厂的说法，为了避免在客户程序的对象出现&#34;if...else...&#34;代码难以扩展以及维护，这里创建一个工厂类来封装这些对象，那这个就应用了简单工厂的方式。<br/><br/>这个场景是这样，有个博客网站，在网站中用户分为几种类型，我这里暂且暂且分为游客，博客会员，超级管理员三种用户权限：<br/>&nbsp;&nbsp; 游客只能进行简单的查看博客的文章，个人资料等等；<br/>&nbsp;&nbsp; 博客会员还可以对自己的博客进行管理； <br/>&nbsp;&nbsp; 超级管理员还可以对于博客系统后台进行管理。<br/>在开始介绍之前，先贴出前两篇介绍的一些接口和类继承的JS文件InterfaceAndClass.js，这里主要要说的是类继承的写法：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function inheritClass(subClass, superClass)<br/>{&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;var Func = function() {};<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(p in superClass.prototype)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Func.prototype[p] = superClass.prototype[p];<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;subClass.prototype = new Func();<br/>&nbsp;&nbsp;&nbsp;&nbsp;subClass.prototype.constructor = subClass;<br/>}<br/></div></div><br/><br/>这里将父类superClass原型的所有方法赋值给新创建的函数类，之后把函数类的原型赋值于子类subClass原型中。<br/><br/>一、现在先对Javascript简单工厂进行介绍：<br/><br/>1. 添加用户类型接口IMember.js：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var IMember = new Interface(&#34;IMember&#34;, [[&#34;getMemberInfo&#34;]]);</div></div><br/><br/>getMemberInfo做为IMember接口的接口方法。<br/><br/>2.&nbsp;&nbsp;添加三个具体用户类型的类Guest.js，BlogMember.js，SuperAdmin.js，继承IMember接口：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>//游客类<br/>function Guest() { <br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IMember); //继承IMember接口<br/>}<br/>Guest.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getMemberInfo : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;游客&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getData : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>//博客会员类<br/>function BlogMember() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IMember);<br/>}<br/>BlogMember.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getMemberInfo : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;博客会员&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getData : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>//超级管理员类<br/>function SuperAdmin() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IMember);<br/>}<br/>SuperAdmin.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getMemberInfo : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;超级管理员&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}, <br/>&nbsp;&nbsp;&nbsp;&nbsp;getData : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>3. 创建一个用户类型工厂类来封装这些用户类型的操作，添加MemberFactory.js：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var MemberFactory = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;cr&#101;ateMemberType : function(memberType) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;&nbsp;_memberType;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(memberType)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;guest&#34;: _memberType = new Guest(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;blogmember&#34;: _memberType = new BlogMember(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;superadmin&#34;: _memberType = new SuperAdmin(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default: _memberType = new BlogMember(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _memberType;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/><br/>通过memberType的“枚举”，创建相应的用户类型类的对象；<br/><br/>4. 至此，通过MemberFactory.cr&#101;ateMemberType的“静态方法”返回一个用户类型对象；<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var member = MemberFactory.cr&#101;ateMemberType(&#34;guest&#34;);&nbsp;&nbsp;//guest, blogmember, superadmin<br/>$(&#34;#result&#34;).html(&#34;您当前为：&#34; + member.getMemberInfo());<br/></div></div><br/><br/>（这里$(“…”)写法是jquery类库中的语法，详细请看官方文档<a href="http://jquery.com/" target="_blank" rel="external">http://jquery.com/</a>）<br/><br/>二、接下来开始本篇的重点，Javascript工厂模式的网站应用<br/><br/>1. 延续上面的博客网站的场景：<br/><br/>&nbsp;&nbsp; 游客只能进行简单的查看博客的文章，个人资料等等；<br/>&nbsp;&nbsp; 博客会员还可以对自己的博客进行管理；<br/>&nbsp;&nbsp; 超级管理员还可以对于博客系统后台进行管理；<br/><br/>这里有这些标签Tab：首页，文章，电影，音乐，相册，关于我，文章管理，个人资料管理，系统后台管理，其中游客只能访问“首页，文章，电影，音乐，相册，关于我”，博客会员（登录后）增加访问“文章管理，个人资料管理”，超级管理员增加访问“系统后台管理”；另外博客会员和超级管理员拥有修改皮肤颜色和版块类型的功能；<br/><br/> 最终页面显示如下所示：<br/><br/><img src="http://www.94this.com.cn/myCode/abstract_factory_class_3.gif" border="0" alt=""/><br/><br/><br/>从图上可以看出，博客会员以上的用户类型可以显示“文章管理，个人资料管理”标签，超级管理员可以显示“系统后台管理”；而布局选择包括“左，中，右结构”，“左，右上，右下结构”，“左上，左下，右结构”，颜色包括“蓝”，“红”，“绿”，“紫”，这里只能博客会员和超级管理员才可以显示；<br/>（这里我使用了网上提供的jquery.tab.js插件对标签进行实现，详细请看<a href="http://stilbuero.de/jquery/tabs_3/" target="_blank" rel="external">http://stilbuero.de/jquery/tabs_3/</a>）<br/><br/>好了，现在开始介绍这个实例通过Javascript工厂模式是如何实现的。<br/><br/>2.&nbsp;&nbsp;IMember.js不变，从简单工厂中直接复制。<br/><br/>3. IMember的具体实现类Guest，BlogMember，SuperAdmin从简单工厂中复制，这里分别添加个原型方法isSetColorBlock，判断该用户类型是否可设置颜色和布局，如下所示：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>Guest.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;//…<br/>&nbsp;&nbsp;&nbsp;&nbsp;isSetColorBlock : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>BlogMember.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;//…<br/>&nbsp;&nbsp;&nbsp;&nbsp;isSetColorBlock : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>SuperAdmin.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;//…<br/>&nbsp;&nbsp;&nbsp;&nbsp;isSetColorBlock : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>可以看到游客不能进行设置，而博客会员和超级管理能进行设置；<br/><br/>4. MemberFactory.js不变，从简单工厂直接复制。<br/><br/>5. 添加IBlock.js，创建布局接口：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var IBlock = new Interface(&#34;IBlock&#34;, [[&#34;getData&#34;]]);</div></div><br/><br/>6. 实现它的具体类，这里添加LMRBlock.js（左 中 右 布局），LRMBlock.js（左上 左下 右 布局），MLRBlock.js（左 右上 右下 布局），这里以LMRBlock.js为例：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>// 左、中、右结构样式版块<br/>function LMRBlock()<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.color = &#34;blue&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IBlock); //继承布局IBlock接口<br/>}<br/>LMRBlock.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;displayBlock : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.getData();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 具体布局实现<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getData : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new Error(&#34;抽象方法，不能调用&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>这里首先创建的是类似于一个抽象类，该类首先继承于布局接口，从代码中可以看出getData方法的实现返回错误异常，实际上它作为一个抽象方法，不需要实现任何东西；这里displayBlock方法中调用它的抽象方法，这里就是典型的<strong>抽象方法模式</strong>，以备于它的子类继承实现它的抽象方法；<br/><br/>现在看看它的子类有哪些：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function BlueLMRBlock(){<br/>}<br/>inheritClass(BlueLMRBlock, LMRBlock); //继承LMRBlock抽象类<br/>BlueLMRBlock.prototype.getData = function() { //父类抽象方法的具体实现<br/>&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;.tabs-nav a, .tabs-nav a span&#34;).css({&#34;background-image&#34;:&#34;url(script/tab/tab_blue.png)&#34;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.color = &#34;blue&#34;;<br/>}<br/><br/>function GreenLMRBlock(){<br/>}<br/>inheritClass(GreenLMRBlock, LMRBlock);<br/>GreenLMRBlock.prototype.getData = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;.tabs-nav a, .tabs-nav a span&#34;).css({&#34;background-image&#34;:&#34;url(script/tab/tab_green.png)&#34;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.color = &#34;green&#34;;<br/>}<br/><br/>function RedLMRBlock(){<br/>}<br/>inheritClass(RedLMRBlock, LMRBlock);<br/>RedLMRBlock.prototype.getData = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;.tabs-nav a, .tabs-nav a span&#34;).css({&#34;background-image&#34;:&#34;url(script/tab/tab_red.png)&#34;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.color = &#34;red&#34;;<br/>}<br/><br/>function VioletLMRBlock(){<br/>}<br/>inheritClass(VioletLMRBlock, LMRBlock);<br/>VioletLMRBlock.prototype.getData = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;.tabs-nav a, .tabs-nav a span&#34;).css({&#34;background-image&#34;:&#34;url(script/tab/tab_violet.png)&#34;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.color = &#34;violet&#34;;<br/>}<br/></div></div><br/>这里包括4种颜色的子类，全部都继承于抽象类LMRBlock，子类中getData的方法做为抽象方法的具体实现；<br/><br/>7. 现在该创建个工厂来实现它们了，添加BlockFactory.js文件，首先创建布局抽象工厂类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function BlockFactory(){<br/>}<br/>BlockFactory.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;getBlock : function(block) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var _block;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_block = this.cr&#101;ateBlock(block);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 添加其他逻辑<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _block;<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;cr&#101;ateBlock : function(block) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new Error(&#34;抽象方法，不能调用&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;getBlockText : function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new Error(&#34;抽象方法，不能调用&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>};<br/></div></div><br/>这里cr&#101;ateBlock和getBlockText同样是做为抽象方法；<br/>现在要创建三个继承于这个布局抽象工厂类，LMRBlockFactory，LRMBlockFactory，MLRBlockFactory，这里同样以LMRBlockFactory为例：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function LMRBlockFactory(){ <br/>}<br/>inheritClass(LMRBlockFactory,BlockFactory);<br/>LMRBlockFactory.prototype.cr&#101;ateBlock = function(block) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var _block;<br/>&nbsp;&nbsp;&nbsp;&nbsp;switch(block)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;blue&#34;: _block = new BlueLMRBlock(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;red&#34;: _block = new RedLMRBlock(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;green&#34;: _block = new GreenLMRBlock(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;violet&#34;: _block = new VioletLMRBlock(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default: _block = new BlueLMRBlock(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;return _block;<br/>};<br/>LMRBlockFactory.prototype.getBlockText = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return &#34;LMR&#34;;<br/>};<br/></div></div><br/>LMRBlockFactory继承于布局抽象工厂类，实现它的抽象方法cr&#101;ateBlock和getBlockText，其中creatBlock通过参数值，创建对应的布局实现类，这里用到了典型的<strong>抽象工厂模式</strong>；<br/><br/>8. 好了，一切都具备好了，现在开始讨论我们的前台使用了，添加factory.html，引用该引用的JS文件，这里列出一些核心代码：<br/><br/>1) 添加初始化数据<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var membertype = &#34;superadmin&#34;; //从用户类型得到值，这里是个假设，包含三个类型用户：guest,blogmember,superadmin<br/>var color = &#34;blue&#34;; //这里是初始化颜色，包括四种颜色：blue,green,red,violet<br/>var blockfactory; //布局工厂类的全局变量声明<br/></div></div><br/>（你可以通过用户登录将登录信息存入cookies中，从cookies获取用户类型和用户选择色调）<br/><br/>2) 初始化用户类型<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>// 初始化用户类型<br/>var member = MemberFactory.cr&#101;ateMemberType(membertype);<br/>$(&#34;#spanMemberType&#34;).html(member.getMemberInfo());<br/>$(&#34;#container-1 li[id^=&#39;li&#39;]&#34;).css(&#34;display&#34;,&#34;block&#34;);<br/>$(&#34;#container-1 li[id^=&#39;li&#39;]&#34;).each(function(index){<br/>&nbsp;&nbsp;&nbsp;&nbsp;var arr = $(this).attr(&#34;power&#34;).split(&#39;|&#39;); //取得对应标签的权限数组<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arr.indexOf(membertype) == -1) //权限比较<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(this).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#fragment-&#34; + (index+1)).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/> });<br/>if(member.isSetColorBlock()) //是否可设置布局和颜色<br/>&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#Set&#34;).css(&#34;display&#34;,&#34;block&#34;);<br/>else<br/>&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#Set&#34;).css(&#34;display&#34;,&#34;none&#34;);<br/>$(&#34;#selMemberType&#34;).val(membertype);<br/></div></div><br/>通过var member = MemberFactory.cr&#101;ateMemberType(membertype);获取用户对象，通过用户对象判断是否可设置布局和颜色；<br/><br/>3) 初始化版块类型和颜色类型<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>// 初始化版块类型和颜色类型<br/>blockfactory = new LMRBlockFactory();<br/>var block = blockfactory.getBlock(color);<br/>block.displayBlock();<br/>$(&#34;img[id^=&#39;imgcolor_&#39;]&#34;).removeClass().addClass(&#34;color-unsel&#101;cted&#34;);<br/>$(&#34;#imgcolor_&#34; + color).removeClass().addClass(&#34;color-sel&#101;cted&#34;);<br/></div></div><br/>通过创建工厂对象，从颜色中获取布局实现类的对象，然后通过调用displayBlock方法的实现初始化界面的布局；<br/><br/>前台JS代码完整实现如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var membertype = &#34;superadmin&#34;; //从用户类型得到值，这里是个假设，包含三个类型用户：guest,blogmember,superadmin<br/>&nbsp;&nbsp;&nbsp;&nbsp;var color = &#34;blue&#34;; //这里是初始化颜色，包括四种颜色：blue,green,red,violet<br/>&nbsp;&nbsp;&nbsp;&nbsp;var blockfactory; //布局工厂类的全局变量声明<br/>&nbsp;&nbsp;&nbsp;&nbsp;$(function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#container-1&#34;).tabs();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 初始化用户类型<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var member = MemberFactory.cr&#101;ateMemberType(membertype);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#spanMemberType&#34;).html(member.getMemberInfo());<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#container-1 li[id^=&#39;li&#39;]&#34;).css(&#34;display&#34;,&#34;block&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#container-1 li[id^=&#39;li&#39;]&#34;).each(function(index){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var arr = $(this).attr(&#34;power&#34;).split(&#39;|&#39;); //取得对应标签的权限数组<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(arr.indexOf(membertype) == -1) //权限比较<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(this).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#fragment-&#34; + (index+1)).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(member.isSetColorBlock()) //是否可设置布局和颜色<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#Set&#34;).css(&#34;display&#34;,&#34;block&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#Set&#34;).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#selMemberType&#34;).val(membertype);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 初始化版块类型和颜色类型<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;blockfactory = new LMRBlockFactory();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var block = blockfactory.getBlock(color);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block.displayBlock();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;img[id^=&#39;imgcolor_&#39;]&#34;).removeClass().addClass(&#34;color-unsel&#101;cted&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#imgcolor_&#34; + color).removeClass().addClass(&#34;color-sel&#101;cted&#34;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 用户类型下拉框绑定<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#selMemberType&#34;).bind(&#34;change&#34;, function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#39;#container-1&#39;).triggerTab(1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var mt = $(this).val();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;membertype = MemberFactory.cr&#101;ateMemberType(mt);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#spanMemberType&#34;).html(membertype.getMemberInfo());<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#container-1 li[id^=&#39;li&#39;]&#34;).css(&#34;display&#34;,&#34;block&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#container-1 li[id^=&#39;li&#39;]&#34;).each(function(index){<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var arr = $(this).attr(&#34;power&#34;).split(&#39;|&#39;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(arr.indexOf(mt) == -1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(this).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#fragment-&#34; + (index+1)).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(membertype.isSetColorBlock())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#Set&#34;).css(&#34;display&#34;,&#34;block&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#Set&#34;).css(&#34;display&#34;,&#34;none&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 版块类型选择<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;img[id^=&#39;imgblock_&#39;]&#34;).bind(&#34;click&#34;, function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if($(this).className != &#34;block-sel&#101;cted&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;img[id^=&#39;imgblock_&#39;]&#34;).removeClass().addClass(&#34;block-unsel&#101;cted&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(this).removeClass().addClass(&#34;block-sel&#101;cted&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var blocktext = $(this).attr(&#34;id&#34;).substring(9);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(blocktext)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;LMR&#34;: blockfactory = new LMRBlockFactory(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;LRM&#34;: blockfactory = new LRMBlockFactory(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#34;MLR&#34;: blockfactory = new MLRBlockFactory(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default: blockfactory = new LMRBlockFactory(); break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var block = blockfactory.getBlock(color);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block.displayBlock();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 颜色选择<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;img[id^=&#39;imgcolor_&#39;]&#34;).bind(&#34;click&#34;, function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;color = $(this).attr(&#34;id&#34;).substring(9);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var block = blockfactory.getBlock(color);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;block.displayBlock();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;img[id^=&#39;imgcolor_&#39;]&#34;).removeClass().addClass(&#34;color-unsel&#101;cted&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(&#34;#imgcolor_&#34; + color).removeClass().addClass(&#34;color-sel&#101;cted&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});<br/>&nbsp;&nbsp;&nbsp;&nbsp;});<br/></div></div><br/><br/>至此，抽象工厂和工厂方法模式的一些思路已经应用在该博客系统中。<br/><br/><br/> 总结<br/><br/>该篇文章用Javascript设计抽象工厂和工厂方法模式的思路，实现一个博客系统的构想。]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/278.htm</link>
			<title><![CDATA[javascript的设计模式之二[观察者模式]]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Tue,19 May 2009 22:15:16 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=278</guid>
		<description><![CDATA[<strong>概述</strong><br/><br/>在现实生活中，存在着“通知依赖关系”，如在报纸订阅的服务，只要读者（订阅者）订购了《程序员》的期刊杂志，那么他就订阅了这个服务，他时刻“监听”着邮递员（出版者）来投递报纸给他们，而邮递员（出版者）只要报社有新刊杂志传达给他（就是状态发生了变化），邮递员（出版者）就随时投递（通知）订阅了服务的读者；另一方面，如果读者不想在继续订购（取消通知）《程序员》的杂志了，那么邮递员就不在投递（通知）这些读者了。－－－这就是典型的出版者和订阅者的关系，而这个关系用一个公式来概括：<br/><br/>出版者 + 订阅者 = 观察者模式<br/><br/><strong>定义</strong><br/><br/><strong>观察者模式</strong>定义了对象之间的一对多依赖，这样一来，当一个对象改变状态时，他的所有依赖者都会收到通知并自动更新。<br/><br/><strong>类图</strong><br/><img src="http://www.94this.com.cn/myCode/javascript2_1.gif" border="0" alt=""/><br/><br/><strong>示例分析</strong><br/><br/>现在开始利用观察者模式来应用到项目的一个场景中去，并且层层剖析一下。<br/><br/>有这样一个场景，一个购书网站，用户提交上去一个订单，网站系统只要有订单上来，会采取如下操作：（为了简化，我这里其实只是简单的提交）<br/><br/>一、产生一条通知用户“已购买”记录的短信息（该短信箱还会有其他记录，如交友等等）；<br/><br/>二、在浏览器上显示你的订单名片；<br/><br/>三、该条订单提交上服务器，保存到数据库或者其它任何存储介质中去，最后显示你的购书记录；<br/><br/>那么开始我的设计：<br/><br/>1. 网站上添加IPublisher.js，它作为系统的出版者“接口”，利用第0篇文章面向对象基础以及接口和继承类的实现中的Interface.js类（另外，谢谢winter-cn园友提出了些宝贵的建议，目前Interface类还在改善中，这里暂且先用原来的Interface类：<br/><br/>这里是改进的程序示范，包括重载函数的构造，这里也暂时贴出来下：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>改进的代码<br/>// Interface.js<br/>function Interface(name, methods) <br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arguments.length != 2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数含&#34; + arguments.length + &#34;个参数, 但需要2个参数.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.methods = [];<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(methods.length &lt; 1) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;第二个参数为空数组.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = methods.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(typeof methods[i][0] !== &#39;string&#39;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数第一个参数必须为字符串类型.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var j = 1; j &lt; methods[i].length; j++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(methods[i][j] &amp;&amp; typeof methods[i][j] !== &#39;number&#39;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数第二个参数以上必须为整数类型.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.methods.push(methods[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br/>};<br/><br/>Interface.registerImplements = function(object) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arguments.length &lt; 2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口的实现必须包含至少2个参数.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 1, len = arguments.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var interface = arguments[i];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(interface.constructor !== Interface) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;从第2个以上的参数必须为接口实例.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var j = 0, methodsLen = interface.methods.length; j &lt; methodsLen; j++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var method1 = interface.methods[j][0];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var arr1 = interface.methods[j].slice(1).sort(compareNumber);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var k = 0; k &lt; object.methodArr.length; k++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var method2 = object.methodArr[k][0];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(method1 === method2)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var arr2 = object.methodArr[k].slice(1).sort();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(ComareArray(arr1,arr2))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口的实现对象不能执行&#34; + interface.name + &#34;的接口方法&#34; + method1 + &#34;，因为它找不到或者不匹配.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>};<br/>function compareNumber(num1, num2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;var iNum1 = parseInt(num1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;var iNum2 = parseInt(num2);<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(iNum1 &lt; iNum2) return -1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;else if(iNum1 &gt; iNum2) return 1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;else return 0;<br/>}<br/>function ComareArray(arr1, arr2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arr1.length!=arr2.length)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0; i &lt; arr1.length; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(arr1[i]!==arr2[i])<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return false;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;return true;<br/>}<br/><br/>Function.prototype.getParameters = function() {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;var str = this.toString();<br/>&nbsp;&nbsp;&nbsp;&nbsp;var paramString = str.slice(str.indexOf(&#39;(&#39;) + 1, str.indexOf(&#39;)&#39;)).replace(/\s*/g,&#39;&#39;);&nbsp;&nbsp;&nbsp;&nbsp; //取得参数字符串<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (paramString.length == 0 ? [] : paramString.split(&#39;,&#39;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;catch(err)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;函数不合法!&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/><br/>// demo.js <br/>function Overload(method)<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.methods = [];<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 1; i &lt;= arguments.length - 1; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methods.push(arguments[i].length);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;OverloadNumber.methodArr.push([arguments[0]].concat(methods));<br/>&nbsp;&nbsp;&nbsp;&nbsp;OverloadNumber.argumentArr.push(arguments);<br/>&nbsp;&nbsp;&nbsp;&nbsp;return function()<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0; i &lt; OverloadNumber.methodArr.length; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(OverloadNumber.methodArr[i][0] == method)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var index = OverloadNumber.methodArr[i].slice(1).indexOf(arguments.length);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(index != -1)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return OverloadNumber.argumentArr[i][index+1].apply(this,arguments);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;参数不匹配!&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>var INumber = new Interface(&#34;INumber&#34;, [[&#34;Add&#34;,1,0,2,3],[&#34;Sub&#34;,1,2]]); //其中1,0,2,3之类属于重载函数参数个数，可以不按先后顺序<br/><br/>function OverloadNumber() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(OverloadNumber, INumber);<br/>}<br/>OverloadNumber.methodArr = [];<br/>OverloadNumber.argumentArr = [];<br/>OverloadNumber.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Add : Overload(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //算术加<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#34;Add&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(a,b) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a + b;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(a) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ++a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(a,b,c) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a+b+c;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;),<br/>&nbsp;&nbsp;&nbsp;&nbsp;Sub : Overload(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //算术减<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#34;Sub&#34;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(a) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return --a;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(a,b) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return a - b;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br/>}<br/></div></div><br/><br/>调用如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>var number = new OverloadNumber();<br/>alert(&#34;4 - 1 = &#34; + number.Sub(4,1));<br/>alert(&#34;++3 = &#34; + number.Add(3));<br/>alert(&#34;4 + 6 = &#34; + number.Add(4, 6));<br/>alert(&#34;4 + 6 + 5 = &#34; + number.Add(4, 6, 5));<br/>alert(number.Add());<br/>alert(&#34;3 - 1 = &#34; + number.Sub(3,1));<br/>alert(&#34;--10 = &#34; + number.Sub(10));<br/>alert(number.Add(4, 6, 5, 9)); // Error！参数不匹配<br/></div></div><br/>－－－－－－－－－－－－－－－－－－－－<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var IPublisher = new Interface(&#39;IPublisher&#39;, [[&#39;registerSubscriber&#39;,1], [&#39;removeSubscriber&#39;,1], [&#39;notifySubscribers&#39;]]);</div></div><br/><br/>所有的依赖者（订阅者）将要注册于它的实现类。<br/><br/>2. 添加ISubscriber.js，它作为系统的订阅者“接口”：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var ISubscriber = new Interface(&#39;ISubscriber&#39;,[[&#39;up&#100;ate&#39;,4]]);</div></div><br/><br/>3. 现在开始实现我们的IPublisher的具体类，添加OrderData.js，它作为一个订单数据类，让其继承IPublisher的接口：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function o&#114;derData() {&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this._subscribers = new Array();&nbsp;&nbsp;//观察者列表<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.ProductName = &#34;&#34;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//商品名称<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.ProductPrice = 0.0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//商品价格<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.Recommend = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //推荐指数<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.productCount = 0;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//购买个数<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, IPublisher);<br/>}<br/><br/>o&#114;derData.prototype = {<br/>&nbsp;&nbsp;&nbsp;&nbsp;registerSubscriber : function(subscriber) { //注册订阅者<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._subscribers.push(subscriber);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;removeSubscriber : function(subscriber) {&nbsp;&nbsp; //删除指定订阅者<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var i = _subscribers.indexOf(subscriber);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(i &gt; 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_subscribers.slice(i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;notifySubscribers : function() {&nbsp;&nbsp;//通知各个订阅者<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0; i &lt; this._subscribers.length; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this._subscribers[i].up&#100;ate(this.ProductName, this.ProductPrice, this.Recommend, this.ProductCount);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;},<br/>&nbsp;&nbsp;&nbsp;&nbsp;SubmitOrder : function(productName,productPrice,recommend,productCount) {&nbsp;&nbsp; //提交订单<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.ProductName = productName;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.ProductPrice = productPrice;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Recommend = recommend;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.ProductCount = productCount;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.notifySubscribers();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/></div></div><br/>这里简单介绍下，OrderData构造函数中设置订阅者列表，以及商品属性；<br/><br/>Interface.registerImplements(this, IPublisher);&nbsp;&nbsp;实际上是让OrderData继承IPublisher接口；<br/><br/>registerSubscriber，removeSubscriber，notifySubscribers实际上覆盖了从 IPublisher继承上来的“接口”方法，这样保存了这个类的方法调用，其中notifySubscribers为通知所有的订阅者更新信息；<br/><br/>4. 实现ISubscriber的具体类，添加Subscriber.js，它里面包含三个订阅者，1）MsgBox类，短信箱列表；2）ThisOrder 类，该条订单名片；3）OrderList类，我的订单列表；并且让其三都继承ISubscriber的“接口”：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>unction MsgBox(publisher)<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.Publisher= publisher;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.Publisher.registerSubscriber(this);<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, ISubscriber);<br/>} <br/>MsgBox.prototype.up&#100;ate = function(productName,productPrice,recommend,productCount) {<br/>//&nbsp;&nbsp;&nbsp;&nbsp;具体实现<br/>} <br/><br/>&nbsp;&nbsp;<br/>function ThisOrder(publisher)<br/>{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;this.Publisher = publisher;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.Publisher.registerPublisher(this);<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, ISubscriber);<br/>} <br/>ThisOrder.prototype.up&#100;ate = function(productName,productPrice,recommend,productCount) { <br/>//&nbsp;&nbsp;&nbsp;&nbsp;具体实现<br/>} <br/><br/>&nbsp;&nbsp;<br/>function o&#114;derList(publisher)<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.Publisher = publisher;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.Publisher.registerPublisher(this);<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, ISubscriber);<br/>} <br/>o&#114;derList.prototype.up&#100;ate = function(productName,productPrice,recommend,productCount) { <br/>//&nbsp;&nbsp;&nbsp;&nbsp;具体实现<br/>} <br/></div></div><br/><br/>看到Subscriber实现类们的构造函数中的内容了么？它把出版者类参数赋值于Subscriber实现类们的Publisher对象，然后在该对象上注册this订阅者自己，这样Publisher对象上就注册了Subscriber对象，并且以Array对象的方式存储起来；<br/><br/>5. 好了，IPublisher.js，ISubscriber.js，OrderData.js，Subscriber.js都创建好了，现在需要一个aspx界面来使用它们了：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&lt;div id=&#34;Container&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;table width=&#34;600px&#34; cellpadding=&#34;0&#34; cellspacing=&#34;1&#34; class=&#34;grid&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;thead&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;商品名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;市场价<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;推荐指数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数量<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/thead&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tbody&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span id=&#34;productName&#34;&gt;你必须知道的.NET&lt;/span&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td align=&#34;center&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span id=&#34;productPrice&#34;&gt;69.8&lt;/span&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td align=&#34;center&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span id=&#34;recommend&#34;&gt;10&lt;/span&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td align=&#34;center&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;span id=&#34;productCount&#34;&gt;1&lt;/span&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tbody&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tfoot&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;td align=&#34;right&#34; colspan=&#34;4&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;input type=&#34;button&#34; id=&#34;btnSubmit&#34; value=&#34; 结 算 &#34; /&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/td&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tfoot&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/table&gt;<br/>&lt;/div&gt;<br/>&lt;div style=&#34;width: 1000px;&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id=&#34;MsgBoxContainer&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h2&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;您的短信箱&lt;/h2&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;table width=&#34;100%&#34; cellspacing=&#34;1&#34; cellpadding=&#34;0&#34; class=&#34;grid&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;thead&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;内容<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th style=&#34;width: 100px;&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;发布日期<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/thead&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tbody id=&#34;MsgBoxResult&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tbody&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/table&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id=&#34;ThisOrderContainer&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h2&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;您刚提交的订单名片&lt;/h2&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id=&#34;ThisOrderResult&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;div id=&#34;OrderListContainer&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;h2&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;您已买的商品列表&lt;/h2&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;table width=&#34;100%&#34; cellspacing=&#34;1&#34; cellpadding=&#34;0&#34; class=&#34;grid&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;thead&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;商品名<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;市场价<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;推荐指数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;数量<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;th style=&#34;width: 100px;&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;发布日期<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/th&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tr&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/thead&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;tbody id=&#34;OrderListResult&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/tbody&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/table&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;div class=&#34;clear&#34;&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/div&gt;<br/>&lt;/div&gt;<br/></div></div><br/><br/>6. 创建一个OrderSend.js，编写相关的JS代码了，以下是核心代码：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>$(&#34;#btnSubmit&#34;).click(function(){<br/>&nbsp;&nbsp;&nbsp;&nbsp;var productName = $(&#34;#productName&#34;).html();<br/>&nbsp;&nbsp;&nbsp;&nbsp;var productPrice = parseFloat($(&#34;#productPrice&#34;).html());<br/>&nbsp;&nbsp;&nbsp;&nbsp;var recommend = parseInt($(&#34;#recommend&#34;).html());<br/>&nbsp;&nbsp;&nbsp;&nbsp;var productCount = parseInt($(&#34;#productCount&#34;).html());<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;var o&#114;derData = new o&#114;derData();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//实例化Publisher的实现类orderData<br/>&nbsp;&nbsp;&nbsp;&nbsp;var msgBox = new MsgBox(orderData);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //orderData作为MsgBox构造函数的参数进行传递 <br/>&nbsp;&nbsp;&nbsp;&nbsp;var thisOrder = new ThisOrder(orderData);&nbsp;&nbsp; //orderData作为ThisOrder构造函数的参数进行传递 <br/>&nbsp;&nbsp;&nbsp;&nbsp;var o&#114;derList = new o&#114;derList(orderData);&nbsp;&nbsp; //orderData作为OrderList构造函数的参数进行传递 <br/>&nbsp;&nbsp;&nbsp;&nbsp;o&#114;derData.SubmitOrder(productName,productPrice,recommend,productCount);&nbsp;&nbsp;&nbsp;&nbsp; //提交相关商品信息<br/>});<br/></div></div><br/><br/>通过点击页面上的“提交”，将三个Subscriber实现类注册到OrderData(Publisher实现类)中去，这样只要OrderData对象提交新商品信息上去，也就是状态更新，那么三个Subscriber实现类就会被通知而更新自身相关的内容了。<br/><br/>页面实现效果如下:<br/><img src="http://www.94this.com.cn/myCode/javascript2_2.gif" border="0" alt=""/><br/><br/>点击“结算”按钮，如下：<br/><img src="http://www.94this.com.cn/myCode/javascript2_3.gif" border="0" alt=""/><br/><br/>这里只是简单的对于三个Subscriber进行更新，关于up&#100;ate方法中的实现，这里不在贴出来了，具体可以下载源代码查看看；在up&#100;ate方法中可以编写你想要的操作以及显示结果，如利用$.ajax进行数据操作和数据展示，这里就留着大家自己发挥吧:)<br/><br/><strong>总结</strong><br/><br/>该篇文章用Javascript来设计观察者模式的思路，通过触发变化通知的方式来请求状态更新，利用一个简单的购书网站来实践。<br/><br/><br/>附：<a target="_blank" href="http://www.94this.com.cn/myCode/Javascri&#112;t_DPObserver_Code.rar" rel="external">代码打包下载</a>]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/277.htm</link>
			<title><![CDATA[javascript的设计模式之一[面向对象基础以及接口和继承类的实现]]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Mon,18 May 2009 23:14:52 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=277</guid>
		<description><![CDATA[<span style="color:Red">javascript方面又出新书了，关于javascript设计模式的，没钱买，所以在网上找了些这方面的文章看看，反正也不是很明白，就转过来，放在这有时间慢慢看了！！当然若你想深入了解javascript，您也不妨看看！！</span><br/><br/><strong>理论知识</strong><br/><br/>1. 首先Javascript是弱类型语言，它定义变量时不必声明类型，如var Person = new Person()，它的变量类型为“var”，现在的C# 3.0也引进了这种匿名类型的概念，弱类型的变量产生了极大的灵活性，因为Javascript会根据需要来进行类型转换。所以这也决定了它采用了晚绑定的方法，即在运行后才知道变量的类型；<br/><br/>2. 面向对象概念不必多说，封装，继承，多态；<br/><br/>3. Javascript对象的类型主要分为三种：本地对象，如String，Array，Date等；内置对象，如Global，Math等；宿主对象，是指BOM,DOM对象等等；变量范围包括传统面向对象程序设计中的作用域，如公有，保护，私有，静态等等；<br/><br/><strong>主要内容</strong><br/><br/>1. 现在让我们来看看Javascript怎样创建对象的：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Man() {<br/>&nbsp;&nbsp; //&nbsp;&nbsp;<br/>}<br/>Man.prototype.getNickName = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return &#34;Leepy&#34;;<br/>}; <br/><br/>var man = new Man();<br/>var name = man.getNickName(); <br/></div></div><br/>这样就创建了最简单的类和对象，其中我们可以把function Man() {} 看作是Man类的构造函数，getNickName()看作是Man类的方法，准确说可以“当作”是Man类的公共方法；为什么要说是当作呢？那是因为其实Javascript实际上并没有一个私有共有的划分，因此开发者们自己指定了这样的规约，那么规约是什么样的呢？我这里把Man类的清单完整地列出来：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Man() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;// 私有静态属性<br/>&nbsp;&nbsp;&nbsp;&nbsp;var Sex = &#34;男&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;//私有静态方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;function checkSex() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (Sex == &#34;男&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;//私有方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;this._getSex = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//调用私有静态方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(checkSex())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;男&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;女&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;//私有方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.getFirstName = function() { <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;Li&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;};<br/>&nbsp;&nbsp;&nbsp;&nbsp;//私有方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.getLastName = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return &#34;Ping&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;};<br/>}<br/>//公共方法<br/>Man.prototype.getNickName = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return &#34;Leepy&#34;;<br/>};<br/>//公共方法<br/>Man.prototype.getFullName = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.getFirstName() + &#34; &#34; + this.getLastName();<br/>};<br/>//公共方法<br/>Man.prototype.getSex = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;//调用私有方法<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this._getSex();<br/>};<br/>//公共静态方法<br/>Man.say = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return &#34;Happy new year!&#34;;<br/>}<br/></div></div><br/>这样的类是否看起来和传统的类很相似了呢^_^ <br/><br/><br/><br/>2. 接下来这个是本篇的一个重点，就是用Javascript如何设计一个接口，然后让类继承于它。 <br/><br/>首先，先让我们看传统的C#语言是如何设计接口的吧：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>public interface Person<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;string GetName();<br/>&nbsp;&nbsp;&nbsp;&nbsp;void SetName(string name);<br/>}<br/>public class Man : Person<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;private string _name; <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;public string GetName()<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return _name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;public void SetName(string name)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>} <br/></div></div><br/>接口中可以声明属性、方法、事件和类型(Structure)，（但不能声明变量），但是并不能设置这些成员的具体值，也就是说，只能定义，不能给它里面定义的东西赋值，而接口作为它的继承类或者派生类的规约，继承类或者它的派生类能够共同完成接口属性、方法、事件和类型的具体实现，因为这里GetName()，SetName()，不管是方法名还是属性调用顺序上都是要保持一致的； <br/><br/>那么有了这样的一个基于接口的思想，我们设计Javascript的接口类的时候也需要考虑到这个规范。我先从主JS文件调用端开始说起：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var Person = new Interface(&#34;Person&#34;, [[&#34;getName&#34;, 0], [&#34;setName&#34;, 1]]); </div></div><br/>其中Interface类是稍后要说的接口类，第一个参数&#34;Person&#34;是接口类的名称，第二个参数是个二维数组，&#34;getName&#34;是接口方法的名称，&#34;0&#34;是该方法所带的参数个数（因为Javascript是弱语言，所以类型是不确定的，所以只要记住参数个数就好，&#34;0&#34;可以省略不写），&#34;setName&#34;同理。这样一个接口定义好了。怎样使用它呢？<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Man() <br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = &#34;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;Interface.registerImplements(this, Person);<br/>}<br/>Man.prototype.getName = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return this.name;<br/>};<br/>Man.prototype.setName = function(name) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>}; <br/></div></div><br/>看到Man的构造函数里面包含<br/><br/>Interface.registerImplements(this, Person); <br/><br/>它是用来将实例化的this对象继承于Person接口，然后继承类对接口的方法进行实现。 <br/><br/>代码看起来是不是很清晰和简单呢^_^，那么现在要开始介绍真正的核心代码Interface.js了： <br/><br/>先看Interface的<strong>构造函数部分</strong><br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function Interface(name, methods) <br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arguments.length != 2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数含&#34; + arguments.length + &#34;个参数, 但需要2个参数.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.methods = [];<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(methods.length &lt; 1) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;第二个参数为空数组.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = methods.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(typeof methods[i][0] !== &#39;string&#39;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数第一个参数必须为字符串类型.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(methods[i][1] &amp;&amp; typeof methods[i][1] !== &#39;number&#39;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数第二个参数必须为整数类型.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(methods[i].length == 1) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methods[i][1] = 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.methods.push(methods[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br/>};<br/></div></div><br/><br/>刚才看到了var Person = new Interface(&#34;Person&#34;, [[&#34;getName&#34;, 0], [&#34;setName&#34;, 1]]);，这里将两个参数分别保存起来； <br/><br/><strong>调用方法部分：</strong><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">Interface.registerImplements = function(object) { <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arguments.length &lt; 2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口的实现必须包含至少2个参数.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;} <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 1, len = arguments.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var interface = arguments[i];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(interface.constructor !== Interface) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;从第2个以上的参数必须为接口实例.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var j = 0, methodsLen = interface.methods.length; j &lt; methodsLen; j++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var method = interface.methods[j][0];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!object[method] || typeof object[method] !== &#39;function&#39; || object[method].getParameters().length != interface.methods[j][1]) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口的实现对象不能执行&#34; + interface.name + &#34;的接口方法&#34; + method + &#34;，因为它找不到或者不匹配.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}; <br/></div></div><br/>刚才这句Interface.registerImplements(this, Person);，实际上这里是把this对象的方法名以及参数个数与刚Person保存的methods逐一进行比较，如果找不到或者不匹配，就警告错误；其中object[method].getParameters().length，调用了如下的代码：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>Function.prototype.getParameters = function() { <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;var str = this.toString();<br/>&nbsp;&nbsp;&nbsp;&nbsp;var paramString = str.slice(str.indexOf(&#39;(&#39;) + 1, str.indexOf(&#39;)&#39;)).replace(/\s*/g,&#39;&#39;);&nbsp;&nbsp;&nbsp;&nbsp; //取得参数字符串<br/>&nbsp;&nbsp;&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (paramString.length == 0 ? [] : paramString.split(&#39;,&#39;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;catch(err)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;函数不合法!&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>} <br/></div></div><br/>getParrameters()方法作为Function对象的一个扩展，功能是取得方法含有的参数数组；<br/><br/>Interface.js完整的代码如下：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">function Interface(name, methods) <br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arguments.length != 2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数含&#34; + arguments.length + &#34;个参数, 但需要2个参数.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.methods = [];<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(methods.length &lt; 1) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;第二个参数为空数组.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 0, len = methods.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(typeof methods[i][0] !== &#39;string&#39;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数第一个参数必须为字符串类型.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(methods[i][1] &amp;&amp; typeof methods[i][1] !== &#39;number&#39;) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口构造函数第二个参数必须为整数类型.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(methods[i].length == 1) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;methods[i][1] = 0;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.methods.push(methods[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br/>}; <br/><br/>Interface.registerImplements = function(object) { <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;if(arguments.length &lt; 2) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口的实现必须包含至少2个参数.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;} <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;for(var i = 1, len = arguments.length; i &lt; len; i++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var interface = arguments[i];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(interface.constructor !== Interface) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;从第2个以上的参数必须为接口实例.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(var j = 0, methodsLen = interface.methods.length; j &lt; methodsLen; j++) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var method = interface.methods[j][0];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!object[method] || typeof object[method] !== &#39;function&#39; || object[method].getParameters().length != interface.methods[j][1]) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;接口的实现对象不能执行&#34; + interface.name + &#34;的接口方法&#34; + method + &#34;，因为它找不到或者不匹配.&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}; <br/><br/>Function.prototype.getParameters = function() { <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;var str = this.toString();<br/>&nbsp;&nbsp;&nbsp;&nbsp;var paramString = str.slice(str.indexOf(&#39;(&#39;) + 1, str.indexOf(&#39;)&#39;)).replace(/\s*/g,&#39;&#39;);&nbsp;&nbsp;&nbsp;&nbsp; //取得参数字符串<br/>&nbsp;&nbsp;&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return (paramString.length == 0 ? [] : paramString.split(&#39;,&#39;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;catch(err)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw new Error(&#34;函数不合法!&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>} <br/></div></div><br/>好了该创建一个html页面来试试效果了：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>&lt;script type=&#34;text/javascript&#34;&gt;<br/>function test()<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;var man = new Man();<br/>&nbsp;&nbsp;&nbsp;&nbsp;man.setName(&#34;Leepy&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;alert(man.getName());<br/>}<br/>&lt;/script&gt; <br/><br/>&lt;input type=&#34;button&#34; value=&#34;click&#34; onclick=&#34;test();&#34; /&gt;<br/></div></div><br/>最终结果为：&#34;Leepy&#34;的弹出框； <br/><br/>这里还有一点要强调，如果接口上的方法没有在继承类上得到完全实现，或者方法参数个数不匹配，那么就会提示错误；<br/><br/>3. 如果我要一个类继承于另一个类该怎么做呢，继续看例子，这里我再定义一个SchoolBoy（男学生）类：<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>function SchoolBoy(classNo, post)<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;Man.call(this);<br/>&nbsp;&nbsp;&nbsp;&nbsp;this._chassNo = classNo;<br/>&nbsp;&nbsp;&nbsp;&nbsp;this._post = post;<br/>}<br/>SchoolBoy.prototype = new Man();<br/>SchoolBoy.prototype.getName = function() {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return &#34;Mr &#34; + this.name;<br/>}<br/>SchoolBoy.prototype.setName = function(name) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;this.name = name + &#34;&#39;s&#34;;<br/>}<br/></div></div><br/>其中Man.call(this);实际上是将Man中的关键字this赋值于SchoolBoy对象中去，那么SchoolBoy就拥有了Man构造函数中的name属性了；<br/><br/>SchoolBoy.prototype = new Man();实际上是把Man的prototype赋值给SchoolBoy.prototype，那么SchoolBoy就有了Man类中的方法；<br/><br/>而后面跟着的getName()，setName()，实际上是覆盖了前面继承于Man类中的方法了；<br/><br/>然后看看效果：<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent">var schoolboy = new SchoolBoy(&#34;三年二班&#34;, &#34;班长&#34;);<br/>schoolboy.setName(&#34;周杰伦&#34;);<br/>alert(schoolboy.getName());<br/></div></div><br/><br/>最后结果为：&#34;Mr 周杰伦&#39;s&#34;的弹出框；<br/><br/><strong>总结 </strong><br/><br/>该篇文章主要讲述一些Javascript面向对象的基础以及接口和继承类的实现等等；下一篇将开始真正的Javascript设计模式征程，并且我会结合一些网站系统上的实例来讲；<br/>]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/262.htm</link>
			<title><![CDATA[用localeCompare实现中文排序]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Sat,29 Nov 2008 22:10:19 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=262</guid>
		<description><![CDATA[大家肯定做过中文的排序了，呵呵是不是代码很多啊，看看这个例子，用localeCompare来实现中文的按拼音首字母排序很简单。<br/><div class="UBBPanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/html.gif" style="margin:0px 2px -3px 0px"> HTML代码</div><div class="UBBContent"><TEXTAREA rows="8" id="temp13344">
<SCRIPT type=&#34;text/javascript&#34;>
function defaultSort(){
var a=&#34;zhishi,english,我lai,lai了,中国,测试,房地产&#34;;
a=a.split(&#34;,&#34;);
a.sort();
alert(a);
}
function cusSort(){
var a=&#34;zhishi,english,我lai,lai了,中国,测试,房地产&#34;;
a=a.split(&#34;,&#34;);
a.sort(function(a,b){
  return a.localeCompare(b);
});
alert(a);
}
</SCRIPT>
<a href=&#34;#&#34; onClick=&#34;defaultSort();&#34;>默认排序</a><br>
<a href=&#34;#&#34; onClick=&#34;cusSort();&#34;>拼音排序</a>
</TEXTAREA><br/><INPUT onclick="runEx('temp13344')"  type="button" class="userbutton" value="运行此代码"/> <INPUT onclick="doCopy('temp13344')"  type="button" class="userbutton" value="复制此代码"/> <INPUT onclick="saveCode('temp13344')" type="button" class="userbutton" value="保存此代码"><br/> [Ctrl+A 全部选择 提示：你可先修改部分代码，再按运行]</div></div>]]></description>
		</item>
		
			<item>
			<link>http://www.94this.com.cn/article/261.htm</link>
			<title><![CDATA[让input也有hover,focus]]></title>
			<author>hi_94this@163.com(亮亮)</author>
			<category><![CDATA[javascript]]></category>
			<pubDate>Sat,29 Nov 2008 21:55:46 +0800</pubDate>
			<guid>http://www.94this.com.cn/default.asp?id=261</guid>
		<description><![CDATA[在css中使用伪类能很容易实现一些效果，但ie7以下的版本，除了支持a的伪类外，其他不支持，解决办法是用onmouseover、onmouseout来实现，当然下面的解决办法也是用了onmouseover、onmouseout的道理来解决，只是使用起来更方便而已。<br/>好了看看效果吧！<br/><div class="UBBPanel"><div class="UBBTitle"><img src="http://www.94this.com.cn/images/html.gif" style="margin:0px 2px -3px 0px"> HTML代码</div><div class="UBBContent"><TEXTAREA rows="8" id="temp16997">
<script type=&#34;text/javascript&#34;>
function suckerfish(type, tag, parentId) {  
if (window.attachEvent) {  
window.attachEvent(&#34;onload&#34;, function() {  
var sfEls = (parentId==null)?document.getElementsByTagName(tag):document.getElementById(parentId).getElementsByTagName(tag); 
type(sfEls);  
});  
}  
}  
sfHover = function(sfEls) {  
for (var i=0; i < sfEls.length; i++) {  
sfEls[i].onmouseover=function() {  
this.className+=&#34; iptHover&#34;;  
}  
sfEls[i].onmouseout=function() {  
this.className=this.className.replace(new RegExp(&#34; iptHover\\b&#34;), &#34;&#34;);  
}  
}  
}  
sfFocus = function(sfEls) {  
for (var i=0; i < sfEls.length; i++) {  
sfEls[i].onfocus=function() {  
this.className+=&#34; iptFocus&#34;;  
}  
sfEls[i].onblur=function() {  
this.className=this.className.replace(new RegExp(&#34; iptFocus\\b&#34;), &#34;&#34;);  
}  
}  
}
</script>
<style type=&#34;text/css&#34;>
textarea{
border:1px solid #BBE1F1;
width:250px;
height:80px;
}
 .iptHover,input:hover,textarea:hover{
border:1px solid #77C2E3;
}
.iptFocus,input:focus,textarea:focus{
border:1px solid #77C2E3;
background-color:#EFF7FF;
}
</style>
<input type=&#34;text&#34; name=&#34;textfield&#34; /><br />
<textarea name=&#34;textarea&#34;><&#47textarea>
<script type=&#34;text/javascript&#34;>
suckerfish(sfHover, &#34;input&#34;);
suckerfish(sfFocus, &#34;input&#34;);
suckerfish(sfHover, &#34;textarea&#34;);
suckerfish(sfFocus, &#34;textarea&#34;);
</script>
</TEXTAREA><br/><INPUT onclick="runEx('temp16997')"  type="button" class="userbutton" value="运行此代码"/> <INPUT onclick="doCopy('temp16997')"  type="button" class="userbutton" value="复制此代码"/> <INPUT onclick="saveCode('temp16997')" type="button" class="userbutton" value="保存此代码"><br/> [Ctrl+A 全部选择 提示：你可先修改部分代码，再按运行]</div></div>]]></description>
		</item>
		
</channel>
</rss>
