JS 設(shè)計(jì)模式 -- 單例模式

本文參考鏈接:湯姆大叔的博客
深入理解JavaScript系列(25):設(shè)計(jì)模式之單例模式

前言

在傳統(tǒng)開發(fā)工程師眼里,單例就是保證一個(gè)類只有一個(gè)實(shí)例,實(shí)現(xiàn)的方法一般是先判斷實(shí)例存在與否,如果存在直接返回,如果不存在就創(chuàng)建了再返回,這就確保了一個(gè)類只有一個(gè)實(shí)例對(duì)象。在JavaScript里,單例作為一個(gè)命名空間提供者,從全局命名空間里提供一個(gè)唯一的訪問點(diǎn)來訪問該對(duì)象

在JavaScript里,實(shí)現(xiàn)單例的方式有很多種,其中最簡(jiǎn)單的一個(gè)方式是使用對(duì)象字面量的方法,其字面量里可以包含大量的屬性和方法:

下面是我在 FIS從入門到放棄 這個(gè)筆記中使用的示例

//這個(gè)是一個(gè)典型的很簡(jiǎn)單的單例模式的例子
var message = {
    //init 是接收參數(shù)的
    init: function() {
        var me = this;
        console.log('message init');
        me.render();
        me.bind();
    },
    //render 是負(fù)責(zé) render頁(yè)面 
    render: function() {
        var me = this;
        me.btn = $('#btn');
    },
    //bind 是負(fù)責(zé)綁相應(yīng)的元素
    bind: function() {
        var me = this;
        //jQuery.proxy( function, context )
        //function為執(zhí)行的函數(shù),content為函數(shù)的上下文this值會(huì)被設(shè)置成這個(gè)object對(duì)象
        me.btn.on('click',$.proxy(me._go,this));
    },
    _go:function(e){
        console.log(e.target);
    }
}
//將方法導(dǎo)出 這個(gè) module.exports 方法是從 layout.tpl 中引用的 mod.js  中來的
module.exports = message;

下面是我在公司項(xiàng)目中的首次嘗試

//這里用的是單例模式中最簡(jiǎn)單的以字面量的形式進(jìn)行書寫的
var XYQAJS = {
    //將這個(gè)對(duì)象初始化
    init: function () {
        var _me = this;
        _me.render();
        _me.bind();
        _me.imgslide();
    },
    //提供所有需要用到的操作元素
    render: function () {
        var _me = this;
        _me.openAskBtn = $('#openAskBtn');
        _me.closebtn = $('.conform').find('.cf_closebtn');
        _me.QASearchBtn = $('#QASearchBtn');
    },
    //將所有的事件都放到這里綁定
    bind: function () {
        var _me = this;
        //$.proxy(_me.openpopup, this)  返回的其實(shí)是 _me.openpopup() 這個(gè)函數(shù)的上下文
        //【我要提問】彈窗切換
        _me.openAskBtn.on('click', $.proxy(_me.openpopup, this));
        _me.closebtn.on('click', $.proxy(_me.closepopup, this));
        _me.QASearchBtn.on('click', $.proxy(_me.searchkeyword, this));
    },
    //右側(cè)活動(dòng)輪播圖
    imgslide:function(){
        jQuery("#slideBox1").slide({ mainCell: ".bd ul", autoPlay: true, interTime: 3000, effect: "fold", switchLoad: "_src" });
    },
    //打開彈窗
    openpopup: function () {
        $('.conformbg,.conform').show();
    },
    //關(guān)閉彈窗
    closepopup: function () {
        $('.conformbg,.conform').hide();
    },
    //搜索關(guān)鍵詞
    searchkeyword: function () {
        var word = $('#keyword').val();
        //提交數(shù)據(jù)

    }
}
XYQAJS.init();
  • 在瀏覽器的控制臺(tái)中輸出會(huì)發(fā)現(xiàn),將所有的東西都綁在了唯一的 XYQAJS 對(duì)象上
image.png

接著我又將上面的方法寫成可 new 可擴(kuò)展、繼承的

//這里是使用的設(shè)計(jì)模式中的單例模式進(jìn)行書寫的
var XYQACommon = (function(){
    var _module;
    if (_module) {
        return _module;
    }
    _module = this;
    //將這個(gè)對(duì)象初始化
    this.init = function () {
        var _me = this;
        _me.render();
        _me.bind();
        _me.imgslide();
    },
    //提供所有需要用到的操作元素
    this.render = function () {
        var _me = this;
        _me.openAskBtn = $('#openAskBtn');
        _me.closebtn = $('.conform').find('.cf_closebtn');
        _me.QASearchBtn = $('#QASearchBtn');
        _me.listMoreBtn = $(".wbn_det").find(".morebtn");

    },
    //將所有的事件綁定都放到這里
    this.bind = function () {
        var _me = this;
        //$.proxy(_me.openpopup, this)  返回的其實(shí)是 _me.openpopup() 這個(gè)函數(shù)的上下文
        //【我要提問】彈窗切換
        _me.openAskBtn.on('click', $.proxy(_me.openpopup, this));
        _me.closebtn.on('click', $.proxy(_me.closepopup, this));
        _me.QASearchBtn.on('click', $.proxy(_me.searchkeyword, this));
        _me.listMoreBtn.on('click', $.proxy(_me.listMoreShow, this));
    },
    //右側(cè)活動(dòng)輪播圖
    this.imgslide = function () {
        jQuery("#slideBox1").slide({ mainCell: ".bd ul", autoPlay: true, interTime: 3000, effect: "fold", switchLoad: "_src" });
    },
    //打開彈窗
    this.openpopup = function () {
        $('.conformbg,.conform').show();
    },
    //關(guān)閉彈窗
    this.closepopup = function () {
        $('.conformbg,.conform').hide();
    },
    //搜索關(guān)鍵詞
    this.searchkeyword = function () {
        var word = $('#keyword').val();
        //提交數(shù)據(jù)

    },
    //詳情頁(yè)右側(cè) 發(fā)標(biāo)公告 點(diǎn)擊下拉展示全部
    this.listMoreShow = function () {
        var _hide = $(this.listMoreBtn).siblings(".wbn_det_list").not(".active");
        //console.log(_hide);
        if (_hide.is(":hidden")) {
            _hide.slideDown(500);
        } else {
            _hide.slideUp(500);
        }
    }

    return _module;
});

$(function () {
    var xyqaCommon = new XYQACommon();
    xyqaCommon.init();
    xyqaCommon.addFn = function () {
        console.log(0);
    }
    console.log(xyqaCommon);
    var xyqaCommon2 = new XYQACommon();
    console.log(xyqaCommon2);
});
  • 上面的寫法可以使得這個(gè) XYQACommon 對(duì)象可 new 可擴(kuò)展、繼承,可以清楚的看到 xyqaCommon 執(zhí)行 init 之后對(duì)象上多了那些在 render 時(shí)掛載的 jq 元素,還有就是在下面擴(kuò)展了 addFn 并沒有影響到宿主
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 單例模式優(yōu)點(diǎn) 劃分命名空間,減少全局變量 組織代碼為一體,便于閱讀維護(hù) 并非所有的對(duì)象字面量都是單例,比如模擬數(shù)據(jù)...
    bestvist閱讀 382評(píng)論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 34,806評(píng)論 18 399
  • 單例模式(SingletonPattern)一般被認(rèn)為是最簡(jiǎn)單、最易理解的設(shè)計(jì)模式,也因?yàn)樗暮?jiǎn)潔易懂,是項(xiàng)目中最...
    成熱了閱讀 4,546評(píng)論 4 34
  • 前言 本文主要參考 那些年,我們一起寫過的“單例模式”。 何為單例模式? 顧名思義,單例模式就是保證一個(gè)類僅有一個(gè)...
    tandeneck閱讀 2,632評(píng)論 1 8
  • 見到你的第一眼, 我就知道你是我的菜 但卻不可能在我的盤子里
    風(fēng)丶蘇子閱讀 203評(píng)論 0 3

友情鏈接更多精彩內(nèi)容