1. 
          

          1. 新聞動(dòng)態(tài)

            談?wù)剬卫J降睦斫?,如何?shí)現?

            常見(jiàn)問(wèn)題 發(fā)布者:ou3377 2021-12-17 08:59 訪(fǎng)問(wèn)量:108

            圖片

            一、是什么

            單例模式(Singleton Pattern):創(chuàng )建型模式,提供了一種創(chuàng )建對象的最佳方式,這種模式涉及到一個(gè)單一的類(lèi),該類(lèi)負責創(chuàng )建自己的對象,同時(shí)確保只有單個(gè)對象被創(chuàng )建

            在應用程序運行期間,單例模式只會(huì )在全局作用域下創(chuàng )建一次實(shí)例對象,讓所有需要調用的地方都共享這一單例對象,如下圖所示:

            圖片

            從定義上來(lái)看,全局變量好像就是單例模式,但是一般情況我們不認為全局變量是一個(gè)單例模式,原因是:

            • 全局命名污染
            • 不易維護,容易被重寫(xiě)覆蓋

            二、實(shí)現

            javascript中,實(shí)現一個(gè)單例模式可以用一個(gè)變量來(lái)標志當前的類(lèi)已經(jīng)創(chuàng )建過(guò)對象,如果下次獲取當前類(lèi)的實(shí)例時(shí),直接返回之前創(chuàng )建的對象即可,如下:

            // 定義一個(gè)類(lèi)
            function Singleton(name{
                this.name = name;
                this.instance = null;
            }
            // 原型擴展類(lèi)的一個(gè)方法getName()
            Singleton.prototype.getName = function({
                console.log(this.name)
            };
            // 獲取類(lèi)的實(shí)例
            Singleton.getInstance = function(name{
                if(!this.instance) {
                    this.instance = new Singleton(name);
                }
                return this.instance
            };

            // 獲取對象1
            const a = Singleton.getInstance('a');
            // 獲取對象2
            const b = Singleton.getInstance('b');
            // 進(jìn)行比較
            console.log(a === b);

            使用閉包也能夠實(shí)現,如下:

            function Singleton(name{
                this.name = name;
            }
            // 原型擴展類(lèi)的一個(gè)方法getName()
            Singleton.prototype.getName = function({
                console.log(this.name)
            };
            // 獲取類(lèi)的實(shí)例
            Singleton.getInstance = (function({
                var instance = null;
                return function(name{
                    if(!this.instance) {
                        this.instance = new Singleton(name);
                    }
                    return this.instance
                }        
            })();

            // 獲取對象1
            const a = Singleton.getInstance('a');
            // 獲取對象2
            const b = Singleton.getInstance('b');
            // 進(jìn)行比較
            console.log(a === b);

            也可以將上述的方法稍作修改,變成構造函數的形式,如下:

            // 單例構造函數
            function CreateSingleton (name{
                this.name = name;
                this.getName();
            };

            // 獲取實(shí)例的名字
            CreateSingleton.prototype.getName = function({
                console.log(this.name)
            };
            // 單例對象
            const Singleton = (function(){
                var instance;
                return function (name{
                    if(!instance) {
                        instance = new CreateSingleton(name);
                    }
                    return instance;
                }
            })();

            // 創(chuàng )建實(shí)例對象1
            const a = new Singleton('a');
            // 創(chuàng )建實(shí)例對象2
            const b = new Singleton('b');

            console.log(a===b); // true

            三、使用場(chǎng)景

            在前端中,很多情況都是用到單例模式,例如頁(yè)面存在一個(gè)模態(tài)框的時(shí)候,只有用戶(hù)點(diǎn)擊的時(shí)候才會(huì )創(chuàng )建,而不是加載完成之后再創(chuàng )建彈窗和隱藏,并且保證彈窗全局只有一個(gè)

            可以先創(chuàng )建一個(gè)通常的獲取對象的方法,如下:

            const getSingle = function( fn ){
              let result;
              return function(){
                return result || ( result = fn .apply(thisarguments ) );
              }
            }; 

            創(chuàng )建彈窗的代碼如下:

            const createLoginLayer = function(){
              var div = document.createElement( 'div' );
              div.innerHTML = '我是浮窗';
              div.style.display = 'none';
              document.body.appendChild( div );
              return div;
            }; 

            const createSingleLoginLayer = getSingle( createLoginLayer ); 

            document.getElementById( 'loginBtn' ).onclick = function(){
              var loginLayer = createSingleLoginLayer();
              loginLayer.style.display = 'block';
            };

            上述這種實(shí)現稱(chēng)為惰性單例,意圖解決需要時(shí)才創(chuàng )建類(lèi)實(shí)例對象

            并且Vuex、redux全局態(tài)管理庫也應用單例模式的思想,如下圖:

            圖片

            現在很多第三方庫都是單例模式,多次引用只會(huì )使用同一個(gè)對象,如jquery、lodash、moment...



            關(guān)鍵字: 實(shí)現單例模式

            文章連接: http://www.gostscript.com/cjwt/829.html

            版權聲明:文章由 晨展科技 整理收集,來(lái)源于互聯(lián)網(wǎng)或者用戶(hù)投稿,如有侵權,請聯(lián)系我們,我們會(huì )立即刪除。如轉載請保留

            双腿国产亚洲精品无码不卡|国产91精品无码麻豆|97久久久久久久极品|无码人妻少妇久久中文字幕
                1.