搜尋
首頁web前端js教程深入理解JavaScript系列(31):設計模式之代理模式詳解_javascript技巧

介紹

代理,顧名思義就是幫助別人做事,GoF對代理模式的定義如下:

代理模式(Proxy),為其他物件提供一種代理以控制對這個物件的存取。

代理模式使得代理物件控制具體物件的參考。代理幾乎可以是任何對象:文件,資源,記憶體中的對象,或是一些難以複製的東西。

正文

我們來舉一個簡單的例子,假如dudu要送酸奶小妹玫瑰花,卻不知道她的聯絡方式或不好意思,想委託大叔去送這些玫瑰,那大叔就是個代理(其實挺好的,可以扣幾朵給媳婦),那我們要如何來做呢?

複製程式碼 程式碼如下:

// 先宣告美女物件
var girl = function (name) {
    this.name = name;
};

// 這是dudu
var dudu = function (girl) {
    this.girl = girl;
    this.sendGift = function (gift) {
        alert("Hi " girl.name ", dudu送你一份禮物:" gift);
    }
};

// 叔叔是代理
var proxyTom = function (girl) {
    this.girl = girl;
    this.sendGift = function (gift) {
        (new dudu(girl)).sendGift(gift); // 為dudu送花咯
    }
};

呼叫方式就非常簡單了:

複製程式碼 程式碼如下:

var proxy = new proxyTom(new girl("酸奶小妹"));
proxy.sendGift("999朵玫瑰");

實戰一把

透過上面的程式碼,相信大家對代理模式已經非常清楚了,我們來實戰下:我們有一個簡單的播放列表,需要在點擊單個連接(或者全選)的時候在該連接下方顯示視頻曲介紹以及play按鈕,點擊play按鈕的時候播放視頻,列表結構如下:

複製程式碼 程式碼如下:

我們先來分析如下,首先我們不僅要監控a連接的點擊事件,還要監控「全選/反選」的點擊事件,然後請求伺服器查詢視訊信息,組裝HTML信息顯示在li元素的最後位置上,效果如下:

然後再監控play連線的點擊事件,點選以後開始播放,效果如下:

好了,開始,沒有jQuery,我們自訂一個選擇器:

複製程式碼 程式碼如下:

var $ = function (id) {
    return document.getElementById(id);
};

由於Yahoo的json服務提供了callback參數,所以我們傳入我們自訂的callback以便來接受數據,具體查詢字串拼裝程式碼如下:
複製程式碼 程式碼如下:

var http = {
    makeRequest: function (ids, callback) {
        var url = 'http://query.yahooapis.com/v1/public/yql?q=',
            sql = 'select * from music.video.id where ids IN ("%ID%")',
            format = "format=json",
            handler = "callback=" callback,
            script = document.createElement('script');

            sql = sql.replace('%ID%', ids.join('","'));
            sql = encodeURIComponent(sql);

            url = sql '&' format '&' handler;
            script.src = url;

        document.body.appendChild(script);
    }
};

代理物件如下:

複製程式碼 程式碼如下:

var proxy = {
    ids: [],
    delay: 50,
    timeout: null,
    callback: null,
    context: null,
    // 設定請求的id和callback以便在播放的時候觸發回呼
    makeRequest: function (id, callback, context) {

        // 新增至佇列dd to the queue
        this.ids.push(id);

        this.callback = callback;
        this.context = context;

        // 設定timeout
        if (!this.timeout) {
            this.timeout = setTimeout(function () {
                proxy.flush();
            }, this.delay);
        }
    },
    // 觸發請求,使用代理職責呼叫了http.makeRequest
    flush: function () {
        // proxy.handler為請求yahoo時的callback
        http.makeRequest(this.ids, 'proxy.handler');
        // 請求資料以後,並緊接著執行proxy.handler方法(裡面有另一個設定的callback)
       
        // 清楚timeout與佇列
        this.timeout = null;
        this.ids = [];

    },
    handler: function (data) {
        var i, max;

        // 單一視訊的callback呼叫
        if (parseInt(data.query.count, 10) === 1) {
            proxy.callback.call(proxy.context, data.query.results.Video);
            return;
        }

        // 多個視訊的callback呼叫
        for (i = 0, max = data.query.results.Video.length; i             proxy.callback.call(proxy.context, data.query.results.Video[i]);
        }
    }
};

影片處理模組主要有3種子功能:取得資訊、展示資訊、播放影片:

複製程式碼 程式碼如下:

var 影片 = {
    // 初始化播放器程式碼,開始播放
    getPlayer: 函數 (id) {
        返回 '
            ''
            ''
            ''
'
            ''
            '             '高度=「255」'
            '寬度=「400」'
            'id="uvp_fop" '
            'allowFullScreen="true" '
            'src="http://d.yimg.com/m/up/fop/embedflv/swf/fop.swf" '
            'type="application/x-shockwave-flash" '
            'flashvars="id=v' id '&eID=1301797&lang=us&ympsc=4195329&enableFullScreen=1&shareEnable=1"'
            '/>'
            '對象>';
                },
    // 貼上資訊顯示內容,然後在附加到li的底部顯示
    updateList:函數(資料){
        變數 ID,
            html = '',             資訊;


        if (data.query) {
            data = data.query.results.Video;
        }
        id = data.id;
        html = '深入理解JavaScript系列(31):設計模式之代理模式詳解_javascript技巧';
        html = '

' data.title '

';
        html = '

' data.copyrightYear ', ' data.label '

';
        if (data.Album) {
            html = '

相簿: 'data.Album.Release.title ', 'data.Album.Release.releaseYear '
';
        }
html = '

»播放

';
        info = document.createElement('div');
        info.id = "訊息" id;
        info.innerHTML = html;
        $('v' id).appendChild(info);
    },
    // 取得資訊並顯示
    getInfo: 函數 (id) {         var info = $('info' id);


        if (!info) {
            proxy.makeRequest(id, 影片.updateList, 影片); //執行代理職責,並決定videos.updateList回呼函數
            返回;

        }

        if (info.style.display === "none") {
            info.style.display = '';
        } else {
            info.style.display = 'none';
        }
    }
};

現在可以處理點擊事件的程式碼了,由於有很多a連接,如果每個連接都綁定事件的話,顯然性能會有問題,所以我們將事件綁定在

    元素上,然後檢測點擊的是否是a連接,如果是說明我們點擊的是視訊地址,然後就可以播放了:

    複製程式碼 程式碼如下:

    $('vids').onclick = function (e) {
        var src, id;

        e = e || window.event;
        src = e.target || e.srcElement;

        // 不是連接的話就不繼續處理了
        if (src.nodeName.toUpperCase() !== "A") {
            return;
        }
        //停止冒泡
        if (typeof e.preventDefault === "function") {
            e.preventDefault();
        }
        e.returnValue = false;

        id = src.href.split('--')[1];

        //如果點選的是已經生產的視訊資訊區域的連結play,就開始播放
        // 然後return不繼續了
        if (src.className === "play") {
            src.parentNode.innerHTML = videos.getPlayer(id);
            return;
        }
           
        src.parentNode.id = "v" id;
        videos.getInfo(id); // 這個才是第一次點選的時候顯示視訊訊息的處理代碼
    };

    全選反選的程式碼大同小異,我們就不解釋了:

    複製程式碼 程式碼如下:

    $('toggle-all').onclick = function (e) {

        var hrefs, i, max, id;

        hrefs = $('vids').getElementsByTagName('a');
        for (i = 0, max = hrefs.length; i         // 忽略play連線
            if (hrefs[i].className === "play") {
                continue;
            }
            // 忽略沒有選擇的項目
            if (!hrefs[i].parentNode.firstChild.checked) {
                continue;
            }

            id = hrefs[i].href.split('--')[1];
            hrefs[i].parentNode.id = "v" id;
            videos.getInfo(id);
        }
    };

    總結

    代理模式一般適用於下列場合:

    1.遠端代理,也就是為了一個物件在不同的位址空間提供局部代表,這樣可以隱藏一個物件存在於不同位址空間的事實,就像web service裡的代理類別。
    2.虛擬代理,根據需要創建開銷很大的對象,透過它來存放實例化需要很長時間的真實對象,比如瀏覽器的渲染的時候先顯示問題,而圖片可以慢慢顯示(就是透過虛擬代理取代了真實的圖片,此時虛擬代理程式保存了真實圖片的路徑和尺寸。 3.安全代理,用來控制真實物件存取時的權限,一般用於物件應該有不同的存取權限。
    4.智能指引,只當呼叫真實的對象時,代理處理另外一些事情。例如C#裡的垃圾回收,使用物件的時候會有引用次數,如果物件沒有引用了,GC就可以回收它了。

    參考:《大話設計模式》

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python vs. JavaScript:開發人員的比較分析Python vs. JavaScript:開發人員的比較分析May 09, 2025 am 12:22 AM

Python和JavaScript的主要區別在於類型系統和應用場景。 1.Python使用動態類型,適合科學計算和數據分析。 2.JavaScript採用弱類型,廣泛用於前端和全棧開發。兩者在異步編程和性能優化上各有優勢,選擇時應根據項目需求決定。

Python vs. JavaScript:選擇合適的工具Python vs. JavaScript:選擇合適的工具May 08, 2025 am 12:10 AM

選擇Python還是JavaScript取決於項目類型:1)數據科學和自動化任務選擇Python;2)前端和全棧開發選擇JavaScript。 Python因其在數據處理和自動化方面的強大庫而備受青睞,而JavaScript則因其在網頁交互和全棧開發中的優勢而不可或缺。

Python和JavaScript:了解每個的優勢Python和JavaScript:了解每個的優勢May 06, 2025 am 12:15 AM

Python和JavaScript各有優勢,選擇取決於項目需求和個人偏好。 1.Python易學,語法簡潔,適用於數據科學和後端開發,但執行速度較慢。 2.JavaScript在前端開發中無處不在,異步編程能力強,Node.js使其適用於全棧開發,但語法可能複雜且易出錯。

JavaScript的核心:它是在C還是C上構建的?JavaScript的核心:它是在C還是C上構建的?May 05, 2025 am 12:07 AM

javascriptisnotbuiltoncorc; sanInterpretedlanguagethatrunsonenginesoftenwritteninc.1)JavascriptwasdesignedAsignedAsalightWeight,drackendedlanguageforwebbrowsers.2)Enginesevolvedfromsimpleterterpretpretpretpretpreterterpretpretpretpretpretpretpretpretpretcompilerers,典型地,替代品。

JavaScript應用程序:從前端到後端JavaScript應用程序:從前端到後端May 04, 2025 am 12:12 AM

JavaScript可用於前端和後端開發。前端通過DOM操作增強用戶體驗,後端通過Node.js處理服務器任務。 1.前端示例:改變網頁文本內容。 2.後端示例:創建Node.js服務器。

Python vs. JavaScript:您應該學到哪種語言?Python vs. JavaScript:您應該學到哪種語言?May 03, 2025 am 12:10 AM

選擇Python還是JavaScript應基於職業發展、學習曲線和生態系統:1)職業發展:Python適合數據科學和後端開發,JavaScript適合前端和全棧開發。 2)學習曲線:Python語法簡潔,適合初學者;JavaScript語法靈活。 3)生態系統:Python有豐富的科學計算庫,JavaScript有強大的前端框架。

JavaScript框架:為現代網絡開發提供動力JavaScript框架:為現代網絡開發提供動力May 02, 2025 am 12:04 AM

JavaScript框架的強大之處在於簡化開發、提升用戶體驗和應用性能。選擇框架時應考慮:1.項目規模和復雜度,2.團隊經驗,3.生態系統和社區支持。

JavaScript,C和瀏覽器之間的關係JavaScript,C和瀏覽器之間的關係May 01, 2025 am 12:06 AM

引言我知道你可能會覺得奇怪,JavaScript、C 和瀏覽器之間到底有什麼關係?它們之間看似毫無關聯,但實際上,它們在現代網絡開發中扮演著非常重要的角色。今天我們就來深入探討一下這三者之間的緊密聯繫。通過這篇文章,你將了解到JavaScript如何在瀏覽器中運行,C 在瀏覽器引擎中的作用,以及它們如何共同推動網頁的渲染和交互。 JavaScript與瀏覽器的關係我們都知道,JavaScript是前端開發的核心語言,它直接在瀏覽器中運行,讓網頁變得生動有趣。你是否曾經想過,為什麼JavaScr

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用