脚本宝典收集整理的这篇文章主要介绍了

js设计模式–单例模式

脚本宝典小编觉得挺不错的,现在分享给大家,也给大家做个参考,希望能帮助你少写一行代码,多一份安全和惬意。
<p><code></p> <h1 id="articleHeader0">前言</h1> <p><strong>本系列文章主要根据《JavaScript设计模式与开发实践》整理而来,其中会加入了一些自己的思考</strong>。希望对大家有所帮助。</p> <h2 id="articleHeader1">文章系列</h2> <p><a href="https://segmentfault.com/a/1190000017717841">js设计模式--单例模式</a></p> <p><a href="https://segmentfault.com/a/1190000017721211" target="_blank">js设计模式--策略模式</a></p> <p><a href="https://segmentfault.com/a/1190000017743794">js设计模式--代理模式</a></p> <h1 id="articleHeader2">概念</h1> <p>单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的全局访问点。</p> <h1 id="articleHeader3">UML类图</h1> <p><span class="img-wrap"><img data-src="/img/bVbmvnB?w=573&amp;h=158" src="https://static.segmentfault.com/v-5cc2cd8e/global/img/squares.svg" alt="clipboard.png" title="clipboard.png" style="cursor: pointer;"></span></p> <h1 id="articleHeader4">场景</h1> <p>单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如<strong>线程池、全局缓存、浏 览器中的 w<a href="http://www.js-code.com/tag/in" title="in" target="_blank">in</a><a href="http://www.js-code.com/tag/do" title="do" target="_blank">do</a>w</strong> 对象等。</p> <p>在 JavaScript 开发中,单例模式的用途同样非常广泛。试想一下,当我们单击登录按钮的时候,页面中会出现一个登录浮窗,而这个<strong>登录浮窗</strong>是唯一的,无论单击多少 次登录按钮,这个浮窗都只会被创建一次,那么这个登录浮窗就适合用单例模式来创建。</p> <h1 id="articleHeader5">优缺点</h1> <p>优点:创建对象和管理单例的职责被分布在两个不同的方法中</p> <h1 id="articleHeader6">实现</h1> <h2 id="articleHeader7">1. 我们的第一个单例</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var instance = null var getInstance = function(arg) { if (!instance) { instance = arg } return instance } var a = getInstance('a') var b = getInstance('b') console.log(a===b)" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword"><a href="http://www.js-code.com/tag/var" title="浏览关于“var”的文章" target="_blank" class="tag_link">var</a></span> <a href="http://www.js-code.com/tag/in" title="浏览关于“in”的文章" target="_blank" class="tag_link">in</a>stance = <span class="hljs-literal"><a href="http://www.js-code.com/tag/null" title="浏览关于“null”的文章" target="_blank" class="tag_link">null</a></span> <span class="hljs-keyword">var</span> getInstance = <span class="hljs-function"><span class="hljs-keyword"><a href="http://www.js-code.com/tag/function" title="浏览关于“function”的文章" target="_blank" class="tag_link">function</a></span>(<span class="hljs-params">arg</span>) </span>{ <span class="hljs-keyword"><a href="http://www.js-code.com/tag/if" title="浏览关于“if”的文章" target="_blank" class="tag_link">if</a></span> (!instance) { instance = arg } <span class="hljs-keyword"><a href="http://www.js-code.com/tag/return" title="浏览关于“return”的文章" target="_blank" class="tag_link">return</a></span> instance } <span class="hljs-keyword">var</span> a = getInstance(<span class="hljs-string">'a'</span>) <span class="hljs-keyword">var</span> b = getInstance(<span class="hljs-string">'b'</span>) <span class="hljs-built_in">console</span>.log(a===b)</code></pre> <p>这种定义一个全局变量的方式非常不优雅,也不好复用代码</p> <h2 id="articleHeader8">2. 利用闭包实现单例</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var Singleton = function( name ){ this.name = name; }; Singleton.getInstance = (function(){ var instance = null; return function( name ){ if ( !instance ){ instance = new Singleton( name ); } return instance; } })(); var a = Singleton.getInstance('a') var b = Singleton.getInstance('b') console.log(a===b)" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword">var</span> Sing<a href="http://www.js-code.com/tag/let" title="浏览关于“let”的文章" target="_blank" class="tag_link">let</a>on = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> <a href="http://www.js-code.com/tag/name" title="浏览关于“name”的文章" target="_blank" class="tag_link">name</a> </span>)</span>{ <span class="hljs-keyword"><a href="http://www.js-code.com/tag/this" title="浏览关于“this”的文章" target="_blank" class="tag_link">this</a></span>.name = name; }; Singleton.getInstance = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>)</span>{ <span class="hljs-keyword">var</span> instance = <span class="hljs-literal">null</span>; <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"> name </span>)</span>{ <span class="hljs-keyword">if</span> ( !instance ){ instance = <span class="hljs-keyword"><a href="http://www.js-code.com/tag/new" title="浏览关于“new”的文章" target="_blank" class="tag_link">new</a></span> Singleton( name ); } <span class="hljs-keyword">return</span> instance; } })(); <span class="hljs-keyword">var</span> a = Singleton.getInstance(<span class="hljs-string">'a'</span>) <span class="hljs-keyword">var</span> b = Singleton.getInstance(<span class="hljs-string">'b'</span>) <span class="hljs-built_in">console</span>.log(a===b)</code></pre> <p>有些同学可能对闭包不大理解,下面用函数实现一下</p> <h2 id="articleHeader9">3. 利用函数实现单例</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" function Singleton(name) { this.name = name this.instance = null } Singleton.getInstance = function(name) { if (!this.instance) { this.instance = new Singleton(name) } return this.instance } var a = Singleton.getInstance('a') var b = Singleton.getInstance('b') console.log(a===b) " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Singleton</span>(<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">this</span>.name = name <span class="hljs-keyword">this</span>.instance = <span class="hljs-literal">null</span> } Singleton.getInstance = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">this</span>.instance) { <span class="hljs-keyword">this</span>.instance = <span class="hljs-keyword">new</span> Singleton(name) } <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.instance } <span class="hljs-keyword">var</span> a = Singleton.getInstance(<span class="hljs-string">'a'</span>) <span class="hljs-keyword">var</span> b = Singleton.getInstance(<span class="hljs-string">'b'</span>) <span class="hljs-built_in">console</span>.log(a===b) </code></pre> <p>2,3这两种方式也有缺点,就是我们必须调用getInstance来创建对象,一般我们创建对象都是利用<a href="http://www.js-code.com/tag/new" title="new" target="_blank">new</a>操作符</p> <h2 id="articleHeader10">4. 透明的单例模式</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="var Singleton = (function() { var instance Singleton = function(name) { if (instance) return instance this.name = name return instance = this } return Singleton })() var a = new Singleton('a') var b = new Singleton('b') console.log(a===b) " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-keyword">var</span> Singleton = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> instance Singleton = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">if</span> (instance) <span class="hljs-keyword">return</span> instance <span class="hljs-keyword">this</span>.name = name <span class="hljs-keyword">return</span> instance = <span class="hljs-keyword">this</span> } <span class="hljs-keyword">return</span> Singleton })() <span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> Singleton(<span class="hljs-string">'a'</span>) <span class="hljs-keyword">var</span> b = <span class="hljs-keyword">new</span> Singleton(<span class="hljs-string">'b'</span>) <span class="hljs-built_in">console</span>.log(a===b) </code></pre> <p>这中方法也有点缺点:不符合单一职责原则,这个对象其实负责了两个功能:单例和创建对象</p> <p>下面我们分离这两个职责</p> <h2 id="articleHeader11">5. 利用代理实现单例</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="var People = function(name) { this.name = name } var Singleton = (function() { var instance Singleton = function(name) { if (instance) return instance return instance = new People(name) } return Singleton })() var a = new Singleton('a') var b = new Singleton('b') console.log(a===b) " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-keyword">var</span> People = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">this</span>.name = name } <span class="hljs-keyword">var</span> Singleton = (<span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> instance Singleton = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">if</span> (instance) <span class="hljs-keyword">return</span> instance <span class="hljs-keyword">return</span> instance = <span class="hljs-keyword">new</span> People(name) } <span class="hljs-keyword">return</span> Singleton })() <span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> Singleton(<span class="hljs-string">'a'</span>) <span class="hljs-keyword">var</span> b = <span class="hljs-keyword">new</span> Singleton(<span class="hljs-string">'b'</span>) <span class="hljs-built_in">console</span>.log(a===b) </code></pre> <p>这中方法也有点缺点:代码不能复用。如果我们有另外一个对象也要利用单例模式,那我们不得不写重复的代码</p> <h2 id="articleHeader12">6. 提供通用的单例</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var People = function(name) { this.name = name } var Singleton = function(Obj) { var instance Singleton = function() { if (instance) return instance return instance = new Obj(arguments) } return Singleton } var peopleSingleton = Singleton(People) var a = new peopleSingleton('a') var b = new peopleSingleton('b') console.log(a===b)" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword">var</span> People = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">this</span>.name = name } <span class="hljs-keyword">var</span> Singleton = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">Obj</span>) </span>{ <span class="hljs-keyword">var</span> instance Singleton = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">if</span> (instance) <span class="hljs-keyword">return</span> instance <span class="hljs-keyword">return</span> instance = <span class="hljs-keyword">new</span> Obj(<span class="hljs-built_in"><a href="http://www.js-code.com/tag/arguments" title="浏览关于“arguments”的文章" target="_blank" class="tag_link">arguments</a></span>) } <span class="hljs-keyword">return</span> Singleton } <span class="hljs-keyword">var</span> peopleSingleton = Singleton(People) <span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> peopleSingleton(<span class="hljs-string">'a'</span>) <span class="hljs-keyword">var</span> b = <span class="hljs-keyword">new</span> peopleSingleton(<span class="hljs-string">'b'</span>) <span class="hljs-built_in">console</span>.log(a===b)</code></pre> <p>到这里已经比较完美了,等等这只是<a href="http://www.js-code.com/tag/es5" title="es5" target="_blank">es5</a>的写法,下面我们用<a href="http://www.js-code.com/tag/es6" title="es6" target="_blank">es6</a>来实现一下</p> <h2 id="articleHeader13">7. <a href="http://www.js-code.com/tag/es6" title="es6" target="_blank">es6</a>单例模式</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text="class People { constructor(name) { if (typeof People.instance === 'object') { return People.instance; } People.instance = this; this.name = name return this; } } var a = new People('a') var b = new People('b') console.log(a===b)" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">People</span> </span>{ <span class="hljs-keyword"><a href="http://www.js-code.com/tag/constructor" title="浏览关于“constructor”的文章" target="_blank" class="tag_link">constructor</a></span>(name) { <span class="hljs-keyword">if</span> (<span class="hljs-keyword"><a href="http://www.js-code.com/tag/typeof" title="浏览关于“typeof”的文章" target="_blank" class="tag_link">typeof</a></span> People.instance === <span class="hljs-string">'object'</span>) { <span class="hljs-keyword">return</span> People.instance; } People.instance = <span class="hljs-keyword">this</span>; <span class="hljs-keyword">this</span>.name = name <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>; } } <span class="hljs-keyword">var</span> a = <span class="hljs-keyword">new</span> People(<span class="hljs-string">'a'</span>) <span class="hljs-keyword">var</span> b = <span class="hljs-keyword">new</span> People(<span class="hljs-string">'b'</span>) <span class="hljs-built_in">console</span>.log(a===b)</code></pre> <h1 id="articleHeader14">比较以上几种实现</h1> <ol> <li>用全局变量的第1种方法,应该摒弃</li> <li>用闭包实现的第2种方式,<a href="http://www.js-code.com/tag/in" title="in" target="_blank">in</a>stance 实例对象总是在我们调用 Sing<a href="http://www.js-code.com/tag/let" title="let" target="_blank">let</a>on.getInstance 的时候才被创建,应该摒弃</li> <li>其他方式都是惰性单例(在需要时才创建)</li> </ol> <h1 id="articleHeader15">js的特殊性</h1> <p>我们都知道:JavaScript 其实是一门无类(<a href="http://www.js-code.com/tag/class" title="class" target="_blank">class</a>-free)语言,,生搬单例模式的概念并无意义。</p> <p>单例模式的核心是确保只有一个实例,并提供全局访问。</p> <p>我们可以用一下几种方式来另类实现</p> <h3 id="articleHeader16">1. 全局变量</h3> <p>比如<a href="http://www.js-code.com/tag/var" title="var" target="_blank">var</a> a = {},这时全局就只有一个a对象<br />但全局变量存在很多问题,它很容易造成命名空间污染,我们用以下两种方式解决</p> <h2 id="articleHeader17">2.使用命名空间</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var namespace1 = { a: function () { alert(1); }, b: function () { alert(2); } };" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword">var</span> namespace1 = { <span class="hljs-attr">a</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <a href="http://www.js-code.com/tag/alert" title="浏览关于“alert”的文章" target="_blank" class="tag_link">alert</a>(<span class="hljs-number">1</span>); }, <span class="hljs-attr">b</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ alert(<span class="hljs-number">2</span>); } };</code></pre> <p>另外我们还可以动态创建命名空间</p> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var MyApp = {}; MyApp.namespace = function (name) { var parts = name.split('.'); var current = MyApp; for (var i in parts) { if (!current[parts[i]]) { current[parts[i]] = {}; } current = current[parts[i]]; } }; MyApp.namespace('event'); MyApp.namespace('dom.style'); console.dir(MyApp); // 上述代码等价于: var MyApp = { event: {}, dom: { style: {} } };" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword">var</span> MyApp = {}; MyApp.namespace = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">name</span>) </span>{ <span class="hljs-keyword">var</span> parts = name.split(<span class="hljs-string">'.'</span>); <span class="hljs-keyword">var</span> current = MyApp; <span class="hljs-keyword"><a href="http://www.js-code.com/tag/for" title="浏览关于“for”的文章" target="_blank" class="tag_link">for</a></span> (<span class="hljs-keyword">var</span> i <span class="hljs-keyword">in</span> parts) { <span class="hljs-keyword">if</span> (!current[parts[i]]) { current[parts[i]] = {}; } current = current[parts[i]]; } }; MyApp.namespace(<span class="hljs-string">'<a href="http://www.js-code.com/tag/event" title="浏览关于“event”的文章" target="_blank" class="tag_link">event</a>'</span>); MyApp.namespace(<span class="hljs-string">'<a href="http://www.js-code.com/tag/do" title="浏览关于“do”的文章" target="_blank" class="tag_link">do</a>m.style'</span>); <span class="hljs-built_in">console</span>.dir(MyApp); <span class="hljs-comment">// 上述代码等价于:</span> <span class="hljs-keyword">var</span> MyApp = { <span class="hljs-attr">event</span>: {}, <span class="hljs-attr">dom</span>: { <span class="hljs-attr">style</span>: {} } };</code></pre> <h2 id="articleHeader18">3. 闭包</h2> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var user = (function () { var __name = 'sven', __age = 29; return { getUserInfo: function () { return __name + '-' + __age; } } })();" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword">var</span> user = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> __name = <span class="hljs-string">'sven'</span>, __age = <span class="hljs-number">29</span>; <span class="hljs-keyword">return</span> { <span class="hljs-attr">getUserInfo</span>: <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> __name + <span class="hljs-string">'-'</span> + __age; } } })();</code></pre> <h1 id="articleHeader19">例子</h1> <h2 id="articleHeader20">登录框</h2> <p>下面我们来实现一个点击登录按钮弹出登录框的例子</p> <h3 id="articleHeader21">粗糙的实现</h3> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="<a href="http://www.js-code.com/tag/button" title="button" target="_blank">button</a>" <a href="http://www.js-code.com/tag/class" title="class" target="_blank">class</a>="copyCode code-tool" data-toggle="tooltip" data-placement="<a href="http://www.js-code.com/tag/top" title="top" target="_blank">top</a>" data-clipboard-<a href="http://www.js-code.com/tag/text" title="text" target="_blank">text</a>="<html></p> <p><body><br /> <button id=&quot;loginBtn&quot;>登录</button><br /> </body><br /> <script> <a href="http://www.js-code.com/tag/var" title="var" target="_blank">var</a> loginLayer = (<a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a> () { var <a href="http://www.js-code.com/tag/div" title="div" target="_blank">div</a> = <a href="http://www.js-code.com/tag/document" title="document" target="_blank">document</a>.createElement('<a href="http://www.js-code.com/tag/div" title="div" target="_blank">div</a>'); <a href="http://www.js-code.com/tag/div" title="浏览关于“div”的文章" target="_blank" class="tag_link">div</a>.inner<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a> = '我是登录浮窗'; div.style.display = 'none'; <a href="http://www.js-code.com/tag/do" title="do" target="_blank">do</a>cument.body.appendChild(div); <a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> div; })(); <a href="http://www.js-code.com/tag/document" title="document" target="_blank">document</a>.getElementById('loginBtn').<a href="http://www.js-code.com/tag/onclick" title="onclick" target="_blank">onclick</a> = <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a> () {</p> <p> loginLayer.style.display = 'block'; }; </script></p> <p></html><br /> " title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html"><span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name"><a href="http://www.js-code.com/tag/button" title="浏览关于“button”的文章" target="_blank" class="tag_link">button</a></span> <span class="hljs-attr">id</span>=<span class="hljs-string">"loginBtn"</span>&gt;</span>登录<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">var</span> loginLayer = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> div = <span class="hljs-built_in"><a href="http://www.js-code.com/tag/document" title="浏览关于“document”的文章" target="_blank" class="tag_link">document</a></span>.createElement(<span class="hljs-string">'div'</span>); div.inner<a href="http://www.js-code.com/tag/html" title="浏览关于“HTML”的文章" target="_blank" class="tag_link">HTML</a> = <span class="hljs-string">'我是登录浮窗'</span>; div.style.display = <span class="hljs-string">'none'</span>; <span class="hljs-built_in">document</span>.body.appendChild(div); <span class="hljs-keyword">return</span> div; })(); <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'loginBtn'</span>).<a href="http://www.js-code.com/tag/onclick" title="浏览关于“onclick”的文章" target="_blank" class="tag_link">onclick</a> = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ loginLayer.style.display = <span class="hljs-string">'block'</span>; }; </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span> </code></pre> <p>上面这种方式如果用户没有点击登录按钮,也会在一开始就创建登录框</p> <h3 id="articleHeader22">改进</h3> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="<a href="http://www.js-code.com/tag/button" title="button" target="_blank">button</a>" class="copyCode code-tool" data-toggle="tooltip" data-placement="<a href="http://www.js-code.com/tag/top" title="top" target="_blank">top</a>" data-clipboard-<a href="http://www.js-code.com/tag/text" title="text" target="_blank">text</a>="<br /> <html></p> <p><body><br /> <button id=&quot;loginBtn&quot;>登录</button><br /> </body><br /> <script> var createLoginLayer = <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a> () { var div = document.createElement('div'); div.inner<a href="http://www.js-code.com/tag/html" title="HTML" target="_blank">HTML</a> = '我是登录浮窗'; div.style.display = 'none'; document.body.appendChild(div); <a href="http://www.js-code.com/tag/return" title="return" target="_blank">return</a> div; }; document.getElementById('loginBtn').<a href="http://www.js-code.com/tag/onclick" title="onclick" target="_blank">onclick</a> = <a href="http://www.js-code.com/tag/function" title="function" target="_blank">function</a> () { var loginLayer = createLoginLayer(); loginLayer.style.display = 'block'; }; </script></p> <p></html>" title="" data-original-title="复制"></span> </div> </p></div> <pre class="xml hljs"><code class="html"> <span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"loginBtn"</span>&gt;</span>登录<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript"> <span class="hljs-keyword">var</span> createLoginLayer = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>); div.innerHTML = <span class="hljs-string">'我是登录浮窗'</span>; div.style.display = <span class="hljs-string">'none'</span>; <span class="hljs-built_in">document</span>.body.appendChild(div); <span class="hljs-keyword">return</span> div; }; <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'loginBtn'</span>).onclick = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> loginLayer = createLoginLayer(); loginLayer.style.display = <span class="hljs-string">'block'</span>; }; </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span></code></pre> <p>这种方式每次点击按钮都会创建一个登录框</p> <h3 id="articleHeader23">再改进</h3> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var createLoginLayer = (function () { var div; return function () { if (!div) { div = document.createElement('div'); div.innerHTML = '我是登录浮窗'; div.style.display = 'none'; document.body.appendChild(div); } return div; } })(); document.getElementById('loginBtn').onclick = function () { var loginLayer = createLoginLayer(); loginLayer.style.display = 'block'; };" title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword">var</span> createLoginLayer = (<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> div; <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">if</span> (!div) { div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>); div.innerHTML = <span class="hljs-string">'我是登录浮窗'</span>; div.style.display = <span class="hljs-string">'none'</span>; <span class="hljs-built_in">document</span>.body.appendChild(div); } <span class="hljs-keyword">return</span> div; } })(); <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'loginBtn'</span>).onclick = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> loginLayer = createLoginLayer(); loginLayer.style.display = <span class="hljs-string">'block'</span>; };</code></pre> <p>这种方式不够通用,不符合单一职责原则</p> <h3 id="articleHeader24">再再改进</h3> <div class="widget-codetool" style="display:none;"> <div class="widget-codetool--inner"> <span class="selectCode code-tool" data-toggle="tooltip" data-placement="top" title="" data-original-title="全选"></span><br /> <span type="button" class="copyCode code-tool" data-toggle="tooltip" data-placement="top" data-clipboard-text=" var getSingle = function (fn) { var result; return function () { return result || (result = fn.apply(this, arguments)); } }; var createLoginLayer = function () { var div = document.createElement('div'); div.innerHTML = '我是登录浮窗'; div.style.display = 'none'; document.body.appendChild(div); return div; }; var createSingleLoginLayer = getSingle(createLoginLayer); document.getElementById('loginBtn').onclick = function () { var loginLayer = createSingleLoginLayer(); loginLayer.style.display = 'block'; }; //下面我们再试试创建唯一的iframe 用于动态加载第三方页面: var createSingleIframe = getSingle(function () { var iframe = document.createElement('iframe'); document.body.appendChild(iframe); return iframe; }); document.getElementById('loginBtn').onclick = function () { var loginLayer = createSingleIframe(); loginLayer.src = 'http://baidu.com'; }; " title="" data-original-title="复制"></span> </div> </p></div> <pre class="javascript hljs"><code class="js"> <span class="hljs-keyword">var</span> getSingle = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">fn</span>) </span>{ <span class="hljs-keyword">var</span> result; <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">return</span> result || (result = fn.apply(<span class="hljs-keyword">this</span>, <span class="hljs-built_in">arguments</span>)); } }; <span class="hljs-keyword">var</span> createLoginLayer = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> div = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'div'</span>); div.innerHTML = <span class="hljs-string">'我是登录浮窗'</span>; div.style.display = <span class="hljs-string">'none'</span>; <span class="hljs-built_in">document</span>.body.appendChild(div); <span class="hljs-keyword">return</span> div; }; <span class="hljs-keyword">var</span> createSingleLoginLayer = getSingle(createLoginLayer); <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'loginBtn'</span>).onclick = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> loginLayer = createSingleLoginLayer(); loginLayer.style.display = <span class="hljs-string">'block'</span>; }; <span class="hljs-comment">//下面我们再试试创建唯一的i<a href="http://www.js-code.com/tag/frame" title="浏览关于“frame”的文章" target="_blank" class="tag_link">frame</a> 用于动态加载第三方页面:</span> <span class="hljs-keyword">var</span> createSingleIframe = getSingle(<span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> iframe = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'iframe'</span>); <span class="hljs-built_in">document</span>.body.appendChild(iframe); <span class="hljs-keyword">return</span> iframe; }); <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'loginBtn'</span>).onclick = <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{ <span class="hljs-keyword">var</span> loginLayer = createSingleIframe(); loginLayer.src = <span class="hljs-string">'http://baidu.com'</span>; }; </code></pre> <p>至此已经完美</p> <p></code></p>

总结

以上是脚本宝典为你收集整理的

js设计模式–单例模式

全部内容,希望文章能够帮你解决

js设计模式–单例模式

所遇到的程序开发问题,欢迎加入QQ群277859234一起讨论学习。如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典网站推荐给程序员好友。 本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。

80%的人都看过