成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javascript設(shè)計模式(Alloy Team)

sf190404 / 2913人閱讀

摘要:小明追女神的故事小明遇到了他的女神,打算送一朵鮮花來表白。剛好小明打聽到他和有一個共同的好友,于是小明決定讓來替自己來完成這件事。

1.單例模式

單例模式的核心:
(1)確保只有一個實例
(2)提供全局訪問

用代理實現(xiàn)單例模式:

var ProxySingletonCreateDiv = (function(){
        var instance;
        return function( html ){
            if ( !instance ){
                instance = new CreateDiv( html );
            }
            return instance;
        }
    })();

通用的惰性單例模式:創(chuàng)建登陸懸浮窗

//fn保存創(chuàng)建邏輯
//單例模式:只創(chuàng)建一次
 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";
    };
2.發(fā)布-訂閱者模式

(1)首先要指定好誰充當(dāng)發(fā)布者
(2)然后給發(fā)布者添加一個緩存列表,用于存放回調(diào)函數(shù)以便通知訂閱者
(3)最后發(fā)布消息的時候,發(fā)布者會遍歷這個緩存列表,依次觸發(fā)里面存放的訂閱者函數(shù)

var Event = (function(){
        var clientList = {},
        listen,
        trigger,
        remove;
        listen = function( key, fn ){
            if ( !clientList[ key ] ){
                clientList[ key ] = [];
            }
            clientList[ key ].push( fn );
        };
        trigger = function(){
            var key = Array.prototype.shift.call( arguments ),
            fns = clientList[ key ];
            if ( !fns || fns.length === 0 ){
                return false;
            }
            for( var i = 0, fn; fn = fns[ i++ ]; ){
                fn.apply( this, arguments );
            }
        };
        remove = function( key, fn ){
            var fns = clientList[ key ];
            if ( !fns ){
                return false;
            }
            if ( !fn ){
                fns && ( fns.length = 0 );
            }else{
                for ( var l = fns.length - 1; l >=0; l-- ){
                    var _fn = fns[ l ];
                    if ( _fn === fn ){
                        fns.splice( l, 1 );
                    }
                }
            }
        };
        return {
            listen: listen,
            trigger: trigger,
            remove: remove
        }
    })();

給所有的對象都動態(tài)安裝一個發(fā)布-訂閱功能:

    var installEvent = function( obj ){
        for ( var i in event ){
            obj[ i ] = event[ i ];
        }
    };
3.裝飾著模式

(1)裝飾者模式可以動態(tài)的給某個對象添加一些額外的職責(zé),而不會影響從這個類中派生出的其他對象。
(2)裝飾者也是包裝器:裝飾者模式將一個對象嵌入到另一個對象中,實際上相當(dāng)于這個對象被另一個對象包裝起來,形成一條包裝鏈。

3-1.在不改變原來函數(shù)的情況下給函數(shù)增加新的功能

var a=function(){
        alert(1);
    }
    var _a = a;
    a=function(){
        _a();
        alert(2);
    }

但是這樣做會帶來兩個問題:必須維護(hù)_a這個中間變量;存在this被劫持的問題
3-2.用AOP裝飾函數(shù)

Function.prototype.before = function( beforefn ){
        var __self = this; // 保存原函數(shù)的引用
        return function(){ // 返回包含了原函數(shù)和新函數(shù)的"代理"函數(shù)
            beforefn.apply( this, arguments ); // 執(zhí)行新函數(shù),且保證this 不被劫持,新函數(shù)接受的參數(shù)
        // 也會被原封不動地傳入原函數(shù),新函數(shù)在原函數(shù)之前執(zhí)行
            return __self.apply( this, arguments ); // 執(zhí)行原函數(shù)并返回原函數(shù)的執(zhí)行結(jié)果,
        // 并且保證this 不被劫持
    }
}

Function.prototype.after = function( afterfn ){
    var __self = this;
    return function(){
        var ret = __self.apply( this, arguments );
        afterfn.apply( this, arguments );
        return ret;
    }
};
//調(diào)用:重寫原來函數(shù)
formSubmit = formSubmit.before( validata );

4.策略模式

策略模式的定義是:定義一系列的算法,把它們一個個封裝起來,并且使它們可以相互替換。
4-1.使用策略模式計算獎金
績效為S的人年終獎金是工資的4倍,績效為A的人年終獎金是工資的3倍,績效為B的人年終獎金是工資的2倍

var performanceS = function(){};
    performanceS.prototype.calculate = function( salary ){
        return salary * 4;
    };
    var performanceA = function(){};
    performanceA.prototype.calculate = function( salary ){
        return salary * 3;
    };
    var performanceB = function(){};
    performanceB.prototype.calculate = function( salary ){
        return salary * 2;
    };

    //接下來定義獎金類Bonus:

    var Bonus = function(){
        this.salary = null; // 原始工資
        this.strategy = null; // 績效等級對應(yīng)的策略對象
    };
    Bonus.prototype.setSalary = function( salary ){
        this.salary = salary; // 設(shè)置員工的原始工資
    };
    Bonus.prototype.setStrategy = function( strategy ){
        this.strategy = strategy; // 設(shè)置員工績效等級對應(yīng)的策略對象
    };
    Bonus.prototype.getBonus = function(){ // 取得獎金數(shù)額
        return this.strategy.calculate( this.salary ); // 把計算獎金的操作委托給對應(yīng)的策略對象
    };

    var bonus = new Bonus();
    bonus.setSalary( 10000 );

    bonus.setStrategy( new performanceS() ); // 設(shè)置策略對象
    console.log( bonus.getBonus() ); // 輸出:40000

4-2.javascript版本的策略模式

var strategies = {
        "S": function( salary ){
            return salary * 4;
        },
        "A": function( salary ){
            return salary * 3;
        },
        "B": function( salary ){
            return salary * 2;

        }
    };
    var calculateBonus = function( level, salary ){
        return strategies[ level ]( salary );
    };

    console.log( calculateBonus( "S", 20000 ) ); // 輸出:80000
    console.log( calculateBonus( "A", 10000 ) ); // 輸出:30000

通過使用策略模式重構(gòu)代碼,我們消除了原來程序中大片的條件分支代碼。所有和計算獎金的邏輯不再放在context中,而是分布在各個策略對象中。每個策略對象負(fù)責(zé)的算法已被各自封裝在對象內(nèi)部。當(dāng)我們對這些策略對象發(fā)出“計算獎金”請求時,它們會返回各自不同的計算結(jié)果。

4-3.用策略模式進(jìn)行表單校驗
(1)用戶名不能為空
(2)密碼長度不能少于6位
(3)手機(jī)號碼必須符合格式



    
請輸入用戶名: 請輸入密碼: 請輸入手機(jī)號碼:
5.代理模式

代理模式是為一個對象提供一個代用品或占位符,以便控制對它的訪問。
5-1.小明追女神的故事
小明遇到了他的女神A,打算送一朵鮮花來表白。剛好小明打聽到他和A有一個共同的好友B,于是小明決定讓B來替自己來完成這件事。

var Flower = function(){};
var xiaoming = {
    sendFlower: function( target ){
        var flower = new Flower();
        target.receiveFlower( flower );
    }
};
var A = {
    receiveFlower: function( flower ){
        console.log( "收到花 " + flower );
    }
};
xiaoming.sendFlower( A );


//接下來,我們引入代理B,即小明通過B 來給A 送花:
var Flower = function(){};
var xiaoming = {
    sendFlower: function( target){
        var flower = new Flower();
        target.receiveFlower( flower );
    }
};
var B = {
    receiveFlower: function( flower ){
        A.receiveFlower( flower );
        90 第6 章 代理模式
    }
};
var A = {
    receiveFlower: function( flower ){
        console.log( "收到花 " + flower );
    }
};
xiaoming.sendFlower( B );

//然后選擇A 心情好的時候把花轉(zhuǎn)交給A,代碼如下:

var Flower = function(){};
var xiaoming = {
    sendFlower: function( target){
        var flower = new Flower();
        target.receiveFlower( flower );
    }
};
var B = {
    receiveFlower: function( flower ){
        A.listenGoodMood(function(){ // 監(jiān)聽A 的好心情
            A.receiveFlower( flower );
        });
    }
};

var A = {
    receiveFlower: function( flower ){
        console.log( "收到花 " + flower );
    },
    listenGoodMood: function( fn ){
        setTimeout(function(){ // 假設(shè)10 秒之后A 的心情變好
            fn();
        }, 10000 );
    }
};

xiaoming.sendFlower( B );

var myImage = (function(){
    var imgNode = document.createElement( "img" );
    document.body.appendChild( imgNode );
    return {
        setSrc: function( src ){
            imgNode.src = src;
        }
    }
})();

5-2.保護(hù)代理與虛擬代理
保護(hù)代理:比如B可以幫助A過濾掉一些請求,如送花的人中年齡較大的
虛擬代理:new Flower可能是非常昂貴的,這時候需要B代理去執(zhí)行,代理B在A心情好的時候再執(zhí)行。
5-3.虛擬代理實現(xiàn)圖片預(yù)加載

var myImage = (function(){
        var imgNode = document.createElement( "img" );
        document.body.appendChild( imgNode );
        return function( src ){
            imgNode.src = src;
        }
    })();
    var proxyImage = (function(){
        var img = new Image;
        img.onload = function(){
            myImage( this.src );
        }
        return function( src ){
            myImage( "file:// /C:/Users/svenzeng/Desktop/loading.gif" );
            img.src = src;

        }
    })();
    proxyImage( "http:// imgcache.qq.com/music// N/k/000GGDys0yA0Nk.jpg" );

縱觀整個程序,我們并沒有改變或者增加myImage接口,但是通過代理對象,實際上是給系統(tǒng)添加了新的行為:給img節(jié)點設(shè)置 src和圖片預(yù)加載這兩個功能。
5-4.虛擬代理合并http請求


    1
    2
    3
    4
    5
    6
    7
    8
    9

script.js:

var synchronousFile = function( id ){
        console.log( "開始同步文件,id 為: " + id );
    };

    var proxySynchronousFile = (function(){
        var cache = [], // 保存一段時間內(nèi)需要同步的ID
        timer; // 定時器
        return function( id ){
            cache.push( id );
            if ( timer ){ // 保證不會覆蓋已經(jīng)啟動的定時器
                return;
            }
            timer = setTimeout(function(){
            synchronousFile( cache.join( "," ) ); // 2 秒后向本體發(fā)送需要同步的ID 集合
            clearTimeout( timer ); // 清空定時器
            timer = null;
            cache.length = 0; // 清空ID 集合
        }, 2000 );
        }
    })();

    var checkbox = document.getElementsByTagName( "input" );
    for ( var i = 0, c; c = checkbox[ i++ ]; ){
        c.onclick = function(){
            if ( this.checked === true ){
                proxySynchronousFile( this.id );
            }
        }
    };

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/82818.html

相關(guān)文章

  • 最初,唯有時光記得

    摘要:前言最初,唯有時光記得。起初,按照自己的學(xué)習(xí)習(xí)慣來,一直秉承著好記性不如爛筆頭的學(xué)習(xí)理念,開始做紙質(zhì)的筆記,累計了好多本之后,發(fā)現(xiàn)有很多的不便利,例如圖片隨時要改動注明來源等。微信公眾號微博。 回顧 Retrospect to the past and look into the future 最近在積極地學(xué)習(xí)webview,原本打算整理一下寫成一篇文章。無奈時間有限,暫時沒有把握把w...

    I_Am 評論0 收藏0
  • 最初,唯有時光記得

    摘要:前言最初,唯有時光記得。起初,按照自己的學(xué)習(xí)習(xí)慣來,一直秉承著好記性不如爛筆頭的學(xué)習(xí)理念,開始做紙質(zhì)的筆記,累計了好多本之后,發(fā)現(xiàn)有很多的不便利,例如圖片隨時要改動注明來源等。微信公眾號微博。 回顧 Retrospect to the past and look into the future 最近在積極地學(xué)習(xí)webview,原本打算整理一下寫成一篇文章。無奈時間有限,暫時沒有把握把w...

    lanffy 評論0 收藏0
  • 最初,唯有時光記得

    摘要:前言最初,唯有時光記得。起初,按照自己的學(xué)習(xí)習(xí)慣來,一直秉承著好記性不如爛筆頭的學(xué)習(xí)理念,開始做紙質(zhì)的筆記,累計了好多本之后,發(fā)現(xiàn)有很多的不便利,例如圖片隨時要改動注明來源等。微信公眾號微博。 回顧 Retrospect to the past and look into the future 最近在積極地學(xué)習(xí)webview,原本打算整理一下寫成一篇文章。無奈時間有限,暫時沒有把握把w...

    stackvoid 評論0 收藏0
  • 為eject后的create-react-app配置ESLint

    摘要:一開始我以為是的問題,然后重新手寫了一些配置依然會報錯,證明不是的問題。規(guī)則真的很嚴(yán)格。配置問題按照的文檔默認(rèn)是,按照說明應(yīng)該是不會阻止。 問題 項目一開始使用的是create-react-app創(chuàng)建的,配置的ESLint是用的AlloyTeam的eslint-config-alloy/react, 默認(rèn)配置已經(jīng)很合理了,并且每條配置都有相應(yīng)的說明,只需要再根據(jù)個人喜好修改一些rule...

    Dean 評論0 收藏0
  • 瀏覽器的緩存(2)

    摘要:的兼容性由于是現(xiàn)代的技術(shù),以下的古老瀏覽器是不支持的。當(dāng)然也可以手動指定文件這些瀏覽器都不能直接使用緩存,即可能會要求你重新驗證,或者直接使用服務(wù)器文件。 親,如果你還在為你沒網(wǎng)打開不網(wǎng)頁而煩惱嗎?親,你還在為你web服務(wù)器復(fù)雜的配置項而蛋疼嗎?不要998,manifest抱回家~manifest自H5橫空出世以來給前端網(wǎng)頁的瀏覽帶來了翻天覆地的變化,以前我們的網(wǎng)頁必須在有網(wǎng)的前提下打...

    impig33 評論0 收藏0

發(fā)表評論

0條評論

sf190404

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<