国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript_設(shè)計模式

BDEEFE / 507人閱讀

摘要:設(shè)計模式是一套可復(fù)用的,被眾人知曉,經(jīng)過編目分明的,經(jīng)驗的總結(jié)。創(chuàng)建類安全工廠判斷是否調(diào)用關(guān)鍵字設(shè)計模式設(shè)計模式運算符可以用來判斷某個構(gòu)造函數(shù)的屬性所指向的對象是否存在于另外一個要檢測對象的原型鏈上。

設(shè)計模式

是一套可復(fù)用的,被眾人知曉,經(jīng)過編目分明的,經(jīng)驗的總結(jié)。
作用:使用設(shè)計模式是為了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性

模式類型

創(chuàng)建型設(shè)計模式:解決對象在創(chuàng)建時產(chǎn)生的一系列問題。
結(jié)構(gòu)型設(shè)計模式:解決類或?qū)ο笾g組合時產(chǎn)生的一系列問題
行為型設(shè)計模式:解決類或?qū)ο笾g的交互以及職責(zé)分配的一些列問題

23種設(shè)計模式

創(chuàng)建型模式:單例模式、抽象工廠模式、建造者模式、工廠模式、原型模式。 (5)
結(jié)構(gòu)型模式:適配器模式、橋接模式、裝飾模式、組合模式、外觀模式、享元模式、代理模式。(7)
行為型模式:模版方法模式、命令模式、迭代器模式、觀察者模式、中介者模式、備忘錄模式、解釋器模式(Interpreter模式)、狀態(tài)模式、策略模式、職責(zé)鏈模式(責(zé)任鏈模式)、訪問者模式。(11)

設(shè)計模式,框架,架構(gòu)與庫

設(shè)計模式:是一套被反復(fù)使用、多數(shù)人知曉的、經(jīng)過分類編目的、代碼設(shè)計經(jīng)驗的總結(jié),它強調(diào)的是一個設(shè)計問題的解決方法

框架:軟件框架是項目軟件開發(fā)過程中提取特定領(lǐng)域軟件的共性部分形成的體系結(jié)構(gòu),不同領(lǐng)域的軟件項目有著不同的框架類型。框架不是現(xiàn)成可用的應(yīng)用系統(tǒng)。而是一個半成品,提供了諸多服務(wù),開發(fā)人員進行二次開發(fā),實現(xiàn)具體功能的應(yīng)用系統(tǒng)。 ( 只有基礎(chǔ)公共代碼,而沒有業(yè)務(wù)邏輯的產(chǎn)品,就是框架。)

架構(gòu):簡單的說架構(gòu)就是一個藍圖,是一種設(shè)計方案,將客戶的不同需求抽象成為抽象組件,并能夠描述這些抽象組件之間的通信和調(diào)用,偏重于設(shè)計。框架比架構(gòu)更具體,更偏重于技術(shù)

工具庫:是類(方法)的集合,這些類之間可能是相互獨立的。可以直接調(diào)用它,而不必再寫一個。框架也往往是類(方法)的集合;但框架中的各個類并不是孤立的,而框架中的業(yè)務(wù)邏輯代碼是將不同的類“連”在一起,在它們之間建立協(xié)作關(guān)系

設(shè)計模式研究的是針對單一問題的設(shè)計思路和解決方法,一個模式可應(yīng)用于不同的框架和被不同的語言所實現(xiàn);而框架則是一個應(yīng)用的體系結(jié)構(gòu),是一種或多種設(shè)計模式和代碼的混合體雖然它們有所不同,但卻共同致力于使人們的設(shè)計可以被重用,在思想上存在著統(tǒng)一性的特點,因而設(shè)計模式的思想可以在框架設(shè)計中進行應(yīng)用。

工廠模式 簡單工廠

定義:用來創(chuàng)建一種類型的產(chǎn)品實例,所以他創(chuàng)建的對象單一

特點:

通過將創(chuàng)建過程寄生在工廠內(nèi),可以解決全局變量污染問題

創(chuàng)建的產(chǎn)品對象單一。

對工廠進行改造可以適應(yīng)不同的需求。











批量生產(chǎn)

    
        
        
    
        
        
    
    
    
        
    

第一種:
在外部創(chuàng)建一個批量生產(chǎn)的工廠,然后再內(nèi)部調(diào)用工廠,它的問題是需要另外創(chuàng)建一個工廠

第二種:
通過在工廠方法內(nèi)部進行分支判斷,決定創(chuàng)建單個產(chǎn)品或者品量單品。
這種方式在工廠內(nèi)部調(diào)用該廠,依賴了工廠名稱。

第三種:
通過在工廠方法內(nèi)部進行分支判斷,決定創(chuàng)建單個產(chǎn)品或者品量單品。
這種方式在工廠內(nèi)部調(diào)用了,arguments.callee解決了對工廠名稱的依賴。

寄生增強工廠

通過對寄生在工廠內(nèi)部的對象增添方法屬性,使在不改變原類的基礎(chǔ)上,完成對類的拓展

在工廠內(nèi)部實例化類 這一步叫做寄生

對實例化的類拓展方法和屬性 這一步叫做增強

將這個對象返回。 這一步是工廠。







  
安全工廠模式

又叫:安全類

特點,不論在調(diào)用的時候有沒有new關(guān)鍵字,得到的結(jié)果都是一樣的。

判斷this是否是只想當(dāng)前對象的。通過instanceof

如果是通過new關(guān)鍵字創(chuàng)建的,就直接對this賦值

如果不是,主動創(chuàng)建,并返回該實例。

//創(chuàng)建 Book類
//安全工廠
var Book = function ( title ) {
    
    //判斷是否調(diào)用 new 關(guān)鍵字
    if ( this instanceof Book ) {
        
        this.title = title;
        
    } else {
        
        return new Book(title);    
        
    }
    
}

//var b1 = new Book("設(shè)計模式1");
var b2 = Book("設(shè)計模式2");

//console.log( b1 ,b1 instanceof Book );  //true
console.log( b2 ,b2 instanceof Book ); //true

instanceof運算符可以用來判斷某個構(gòu)造函數(shù)的prototype屬性所指向的對象是否存在于另外一個要檢測對象的原型鏈上。

工廠方法

通過對產(chǎn)品類的抽象使其創(chuàng)建業(yè)務(wù)主要負(fù)責(zé)用于創(chuàng)建多類產(chǎn)品的實例
特點:

創(chuàng)建多類對象

也是對類的再封裝

步驟:

聲明參數(shù)
循環(huán)創(chuàng)建類
對類的添加方法
將實例化對象返回


    
    





原型模式

通過將對象的原型指向類的原型實現(xiàn)對該對象原型的屬性與方法的共享。

var Rect = function( x,y ){
    
    //繼承
    Base.apply(this,arguments);
    this.dom.className = "rect";

}

Rect.prototype = new Base();

原型模式一種創(chuàng)建型設(shè)計模式
它基于javascript原型鏈原理實現(xiàn)的
是一種組合式繼承
對于處理復(fù)雜的類,通過提取公共部分實現(xiàn)對類優(yōu)化

單例模式 簡單單體模式

只能創(chuàng)建一個實例, 把所有代碼和數(shù)據(jù)組織到一個地方. 全局的資源,公共的數(shù)據(jù), 組織到一起.統(tǒng)一的管理.
單體模式 一般不采用new 關(guān)鍵字. 已經(jīng)存在了對象.
主要用來 劃分命名空間(區(qū)分代碼,降低耦合性)

var Singleton={
    attr1: true,
    attr2: 10,
    method1: function(){
        alert(this.attr1);
    },
    method2: function(){
        alert("方法2");
    }
}
惰性單例

借用閉包創(chuàng)建單體 閉包主要的目的:就是保護數(shù)據(jù),不受外界所干擾.
通過閉包將我們的single封裝起來,避免外部訪問而實例化,這樣可保證實例化一次,閉包的返回函數(shù)的作用域在閉包里面,所以可以訪問到single類對其實例化,這樣在執(zhí)行LazySingle才會對single類實例化

特點:
只能被實例化一次
推遲了實例化時間

var _interface = null;

var LazySingle = (function () {
    
    var Signle = function () {
        // do     
    }
    
    Signle.prototype = {
        version: 2,
        sayHello: function () {
            console.log("1");
        }
    }
    
    return function () {
        
        if ( !_interface ) {
            
            _interface = new Signle();
            
        }
        
        return _interface;
        
    }
    
})()


var s = LazySingle();

s.sayHello();
分支單體

判讀程序的分支 --> 瀏覽器差異檢測

var Slington = (function(){
    
    var def = true;

    var More = function(){

        var objA = { //火狐瀏覽器  內(nèi)部的一些配置
            attr1: "ff attr1",
            //屬性1
            //方法1
        }
        var objB = {  //ie瀏覽器 內(nèi)部的一些配置
            attr2: "ie attr1",
            //屬性1
            //方法1
        }

    }
    return (def) ? new More().objA : new More().objB;

})();
適配器模式

將一個類(對象)的接口(屬性或者方法)轉(zhuǎn)化成另一個類(對象)的接口,以滿足用戶的需要,使類(對象)之間接口的不兼容問題得以解決。

對被適配的數(shù)據(jù)的一個分解再封裝的一個過程。
這個過程中會造成一定的開銷。但遠(yuǎn)比更改原有業(yè)務(wù)邏輯成本低。

請求數(shù)據(jù)適配

需要dataAdaptor函數(shù)中有適配映射表

 function DealData ( arr ) {
                
    var div = document.createElement("div");
    var img = new Image();
    var a = document.createElement("a");
    var p = document.createElement("p");
    
    img.src = arr[1];
    a.href = arr[0];
    
    p.innerHTML = arr[2];
    a.appendChild(p);
    a.appendChild(img);
    div.appendChild(a);
    
    document.body.appendChild(div);
    
}


//適配器
function DataAdaptor ( data ) {
    
    var arr = [];
    
    //適配映射表
    var map = {
        "src": 1,
        "href": 0,
        "title": 2
    }
    
    for ( var i in map ) {
        
        //把第三方數(shù)據(jù)源中的數(shù)據(jù),放到自己數(shù)據(jù)中的數(shù)組中的相應(yīng)位置
        //map[i] -> 自己數(shù)據(jù)源中的位置
        //i -> 第三方數(shù)據(jù)源中的屬性
        
        arr[map[i]] = data[i];
        
    }
    
    //匹配出來后的數(shù)據(jù)
//                arr[0] = data.href
//                arr[1] = data.src
//                arr[2] = data.title
    
    return arr;
    
}


//第三方提供數(shù)據(jù)
//           obj.href  : 鏈接地址    
//                obj.src   : 圖片地址
//                obj.title : 圖片標(biāo)題

$.get("xxx.json",function ( oD ) {
    
    if ( oD && oD.errno === 0 ) {
        
        var newRes = new DataAdaptor( oD.data ); 
        
        DealData(newRes);
        
    }
    
})
參數(shù)適配

使用繼承
使用 || 運算符

function extend ( targetObj,obj ) {
                
    for ( var i in obj ) {
        
        targetObj[i] = obj[i];
        
    }
    
    return targetObj;
    
}

var Button = function ( param ) {
    
    var btn = document.createElement("button");
    
    //默認(rèn)參數(shù)
    var def = {
        "background": "tan",
        "color": "yellow",
        "fontSize": "12px",
        "text": "按鈕"
    }
    
    // 適配用戶傳遞的參數(shù)與默認(rèn)的參數(shù)
    var def1 = extend(def,param);
    
    for ( var i in def1 ) {
        
        if ( i === "text" ) {
            
            btn.innerHTML = def1[i];
            
        } else {
            
            btn.style[i] = def1[i];
            
        }
        
    }
    
    document.body.appendChild(btn);
    
}

Button({"background": "deeppink"});
組合模式

部分整體模式,將對象表示成樹形結(jié)構(gòu),表示部分整體關(guān)系。所以部分與整體的行為習(xí)慣達到一致型。

組合模式中只有兩種類型對象,組合對象,葉子對象

創(chuàng)建類的步驟:

構(gòu)造函數(shù)

構(gòu)造函數(shù)繼承

保留參數(shù)

初始化數(shù)據(jù)

原型式繼承,繼承基類方法
重寫init方法
添加其他方法

它是將整體分解成為一個個部分,再有部分重新拼裝成一個整體。部分分解的也多,整合結(jié)果也就越多。
它的部分與整體之間具有行為的一致性。
部分拼裝成整體的過程具有多樣性

觀察者模式

叫消息系統(tǒng),消息機制,或者發(fā)布訂閱模式。通過消息系統(tǒng)實現(xiàn)對象或者類之間的解耦。
解決是一種依賴關(guān)系,
解決了,主體與觀察者之間的一種依賴關(guān)系。
被觀察者對象或者類也可以是觀察者,觀察者也可以是被觀察者
觀察者內(nèi)部變化不會影響到被觀察者,反過來一樣

var Observer = (function () {

var __msg = {};

return {
    
    //添加訂閱者 
    //@param {String} type  訂閱者名字
    //@param {Function} fn  執(zhí)行函數(shù)  
    
    add: function ( type,fn ) {
        
        if ( __msg[type] ) {
            
            __msg[type].push(fn);
            
        }    else {
            
            __msg[type] = [fn];
            
        }
        
        return this;
        
    },

     //執(zhí)行回調(diào)函數(shù)
     //@param {String} type
    fire: function ( type,data ) {
        
        if ( __msg[type] ) {
            
            var e = data
            
            for ( var i=0; i<__msg[type].length; ++i ) {
                
                __msg[type][i](e);
                
            }
            
        }
        
        return this;
        
    },
     // 移除回調(diào)函數(shù)
     // @param {String} type
     // @param {String} fnName
    remove: function ( type,fnName ) {
        
        if ( __msg[type] ) {
            
            for ( var i = __msg[type].length-1; i>=0; --i ) {
                
                if ( __msg[type][i] === fnName ) {
                    
                    __msg[type].splice(i,1);
                    
                }
                
            }
            
        }
        
        return this;
    }
    
}

})()
策略模式

封裝一組算法,使其可以互相替換,這組算法本身具有獨立性,不受客戶端影響。

特點:

它是行為型模式

每種都是獨立的,所他們之間可以相互替換

他解決是使用者與策略算法之間的耦合

算是是獨立的方便我們進行單測

算法在使用時候的過程是不一樣的,但結(jié)果是一樣的

tween中使用的是策略模式,價格算法,表單驗證.



價格:

淘寶價:

//表單驗證

var InputStrategy = (function () {
            
//策略模型
var strategy = {
    
    //判斷是否為空
    "notNull": function ( val ) {
        
        return /^s*$/g.test(val) ? "輸入的內(nèi)容不能為空" : "";
        
    },
    
    //判斷是否是數(shù)字
    "isNumber": function ( val ) {
        
        return /^-?[d]+(.[d])?$/.test(val) ? "" : "輸入的不是一個正確的數(shù)字";
        
    },
    
    //判斷電話格式  010-12345678 1234-1234567
    "isTelephoneNumber": function ( val ) {
        
        return /^[d]{3}-[d]{8}$|^[d]{4}-[d]{7}$ /.test(val) ? "" : "請輸入一個正確的電話號碼";
        
    }
    
}

return {
    //檢測表單輸入的文本內(nèi)容是否正確
    //@param {String} val 檢測文本
    //@param {String} type 檢測算法
    
    check: function ( val,type ) {
        
        if ( strategy[type] ) {
            
            return strategy[type](val);
            
        } else {
            
            return "沒有該算法";
            
        }
        
    }
}

})()


//策略名稱 與 頁面中的表單的 映射表
var arr = ["notNull", "isNumber", "isTelephoneNumber"];

for ( var i=1; i<4; i++ ) {

checkInp( "inp"+i ,"err"+i,arr[i-1] );

}

//執(zhí)行 檢測表單
function checkInp ( inpId,errId,type ) {

//添加監(jiān)聽
document.getElementById(inpId).onblur = function ( ev ) {
    
    var val = ev.target.value;
    
    var reslut = InputStrategy.check( val,type );
    
    if ( reslut ) {
        
        document.getElementById(errId).innerHTML = reslut;
        
    } else {
        
        document.getElementById(errId).innerHTML = "";
        
    }
    
}

}
命令模式

將請求與實現(xiàn)解耦并封裝,實現(xiàn)請求對客戶端實現(xiàn)參數(shù)化。

命令模式渲染視圖

頁面中有好多數(shù)據(jù)源,要對這些數(shù)據(jù)源渲染頁面,傳統(tǒng)方式,渲染頁面時候,將視圖,數(shù)據(jù),業(yè)務(wù)耦合在一起了,不利于開發(fā),所以要將這些實現(xiàn)東西提取出來封裝成一個個命令供使用,來實現(xiàn)代碼復(fù)用,并簡化的創(chuàng)建操作


        

命令模式解決了命令的發(fā)起者與命令的實現(xiàn)者之間的耦合
命令的發(fā)起者(調(diào)用命令的時候) 不必去了解命令是如何實現(xiàn)的以及命令是如何運行的。
所有的在使用具有一致性。
命令模式在一定程度上簡化了操作。

canvas繪圖

canvas繪圖的 上下文 ctx 一些問題

模塊外界訪問不到 ctx
ctx很重要,不論操作都需要使用這個變量
一旦更改這個變量,會造成很嚴(yán)重的后果,造成原有功能失效。

把ctx封裝成內(nèi)部方法。 封裝成 cmd 對象下的方法, 在excute 命令執(zhí)行方法中匹配 cmd 中的方法







迭代器模式 數(shù)組迭代器
// 遍歷
// arr 遍歷的函數(shù)
// cb
function each ( arr,cb ) {
    
    for ( var i=0,len=arr.length; i
對象迭代器
//obj 要被遍歷的對象
//cb 遍歷回調(diào)函數(shù)
function each( obj,cb ){
    for( var i in obj ){
        cb && cb.call(obj,obj[i],i);
    }
}
function each (obj, fn) {
    // obj是一個數(shù)組時候
    if (obj instanceof Array) {  //判斷是否是數(shù)組
        //迭代數(shù)組
        for (var i = 0, len = obj.length; i < len; i++) {
            fn(obj[i], i, obj)
        }
    // obj是一個對象
    } else { 
        // 迭代對象
        for (var i in obj) {
            fn(obj[i], i, obj)
        }
    }
}
面向?qū)ο笾械牡?/b>

面向?qū)ο笾杏袝r需要遍歷實例化對象中的自身屬性,過濾掉原型上的屬性,可以通過 hasOwnPrototy 來實現(xiàn)

// 遍歷實例化對象自身的屬性,過濾掉原型上的屬性
// obj    實例化對象
// cb     回調(diào)函數(shù)

function  each ( obj,cb ) {
    for ( var i in obj ) {
        if ( obj.hasOwnPrototy(i) ) {
            cb && cb.call(obj,obj[i],i);
        }
    }
}

迭代器的特點

本身并沒有刪除循環(huán)語句,只是將循環(huán)語句轉(zhuǎn)移到迭代器的內(nèi)部,

迭代器模式中,數(shù)據(jù)對象內(nèi)部的結(jié)構(gòu),只需要關(guān)注處理函數(shù)。

移出了循環(huán)語句,使得代碼看著更清晰

迭代器模式是將數(shù)據(jù)源于處理函數(shù)之間的解耦

DOM迭代器

        
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
委托模式

是將多個對象接收并處理的請求,統(tǒng)一委托給另外一個對象處理

委托模式解決事件數(shù)量問題

解決事件綁定數(shù)量的問題,為一堆元素綁定事件,通過for循環(huán)遍歷綁定,無形中綁定了n個事件,這樣在內(nèi)存中造成一定的開銷。
可以通過這些元素公共的父元素,對其綁定事件,通過e.target事件觸發(fā)的目標(biāo)元素的某些屬性來確認(rèn)是哪些元素需要綁定事件來解決上面的問題。
通常可以判斷元素的名稱類名id,及其屬性
通過對子元素的某些特性判斷,來實現(xiàn)對該元素的事件的綁定。

var oUl = document.getElementsByTagName("ul")[0];
var li = oUl.getElementsByTagName("li");


oUl.addEventListener("click",function ( e ) {

//                console.log( e );

    if ( e.target.tagName.toLocaleLowerCase() == "li" ) {
        
        e.target.style.background = "pink";
        
    }


},false);
未來元素事件綁定問題

傳統(tǒng)式方式通過for循環(huán),只能對現(xiàn)用元素進行事件綁定,當(dāng)需要在后面添加新的元素的時候,該方案不能對新元素綁定事件。
委托模式,通過將子元素的事件綁定委托給父元素,事件對子元素事件綁定的效果,這樣,在父元素中添加新的子元素,同樣可以獲取綁定事件的效果

var oUl = document.getElementsByTagName("ul")[0];
var li = oUl.getElementsByTagName("li");


oUl.addEventListener("click",function ( e ) {

//                console.log( e );

    if ( e.target.tagName.toLocaleLowerCase() == "li" ) {
        
        e.target.style.background = "pink";
        
    }
    

},false);

var oLi = document.createElement("li");

oLi.innerHTML = "11";

oUl.appendChild(oLi);
jQuery事件委托

jQuery中給我提供了一個專用來是做事件委托事件綁定方法,delegate,它實質(zhì)上是通過on方法實現(xiàn)的


內(nèi)存外泄

在低版本IE瀏覽器中,內(nèi)存只會清理哪些沒有被javascript引用的dom元素,所以在對元素定義事件時候,如果將元素清理一定要將該元素綁定的事件解除,因此要在事件內(nèi)部顯性清除事件綁定,但這就要寫在原有事件內(nèi)部,

var oDiv = document.getElementsByTagName("div")[0];
            
var oBtn = document.getElementsByTagName("button")[0];

oBtn.onclick = function () {
    
    oBtn.onclick = null;  //手動清除事件綁定
    oDiv.innerHTML = "info";
    
}

更好的解決方案是對該元素的父元素委托綁定事件,這樣當(dāng)清理該元素時候,由于沒有事件的綁定,該元素即會被清理

var oDiv = document.getElementsByTagName("div")[0];
            
var oBtn = document.getElementsByTagName("button")[0];

oDiv.onclick = function ( ev ) {
    
    if ( ev.target.tagName.toLocaleLowerCase() === "button" ) {
        
        oDiv.innerHTML = "info";
        
    }
    
}    
數(shù)據(jù)分發(fā)

動態(tài)頁面中,頁面中的每個模塊會對應(yīng)一個數(shù)據(jù)請求,然而如果頁面中的這類模塊很多,就要發(fā)送多個請求,但是并發(fā)請求的個數(shù)是有限的 ,因此后面的請求就會被堵塞,為了解決這類問題,可以將這些請求委托給父請求統(tǒng)一處理,當(dāng)接收數(shù)據(jù)后,解析數(shù)據(jù),并派發(fā)給各個子模塊中,供其使用

//對每個模塊進行封裝
var DealStrategy = {
    
    "banner": function ( data ) {
        
        $(".banner").html(data);
        
    },
    
    "article": function ( data ) {
        
        $(".article").html(data);
        
    },
    
    "aside": function ( data ) {
        
        $(".aside").html(data);
        
    }
    
}

function Deal ( data ) {
    
    for ( var i in data ) {
        
        DealStrategy[i](data[i]);
        
    }
    
}

//發(fā)出 get 請求
$.get("data/all.json",function ( res ) {
    
    if ( res.errno === 0 ) {
        
        Deal( res.data );
        
    }
    
});
節(jié)流模式

對重復(fù)的業(yè)務(wù)邏輯進行節(jié)流控制,執(zhí)行最后一次操作并取消其他操作,以提高性能。

特點:

通過計時器延遲程序的執(zhí)行

通過計時器,使程序異步執(zhí)行,避免開銷大的程序造成的堵塞

條件:

程序可控:即取消后是否可以繼續(xù)執(zhí)行

異步執(zhí)行:即程序是否可以異步執(zhí)行

節(jié)流器

通過jQuery的stop方法禁止動畫的排隊,但是對于滾動這種高頻事件,每次執(zhí)行都會添加動畫
通過節(jié)流模式,短時間內(nèi)觸發(fā)多次動畫時,前面動畫被取消添加,這樣只執(zhí)行最后一次,來提高性能

節(jié)流器通常提供兩種使用方式
觸發(fā)操作
清除操作

//對重復(fù)的業(yè)務(wù)邏輯,通常執(zhí)行最后一個,取消前面的業(yè)務(wù)邏輯,來實現(xiàn)業(yè)務(wù)邏輯的優(yōu)化。
//高頻事件, mousemove ,window.onscorll
var Throttle = function () {


    var isClear = arguments[0] , fn;

    if ( isClear !== "true" ) {

     // 觸發(fā)操作
     // @param[0] [Function]  表示函數(shù)的名稱
     // @param[1] [Object] 配置項

        //觸發(fā)操作
        fn = isClear;
        var o = arguments[1] || {};

        var obj = {
            time: o.time || 200,
            context: o.context || null,
            data: o.data || null
        };  //配置項
        
        //設(shè)表先關(guān)
        fn._throttle && clearTimeout(fn._throttle);
        
        fn._throttle = setTimeout(function(){

            fn.call(obj.context,obj.data);    

        },obj.time);

    } else {

        // 清除操作
        // @param[0] [Boolean] 表示是否取消操作. true 取消
        // @param[1] [Function] 取消的函數(shù)名稱

        //取消操作
        fn = arguments[1];

        //清除定時器
        fn._throttle && clearTimeout(fn._throttle);

    }

}

function goBack(){
    console.log(1);
}

//觸發(fā)
Throttle(goBack,{time: 500,data: {msg: "hello"}});

//清除操作
// Throttle(true,goBack);

統(tǒng)計節(jié)流

統(tǒng)計是什么,為什么要做統(tǒng)計?
統(tǒng)計是為了了解用戶對頁面使用習(xí)慣或者使用方式的,要為頁面添加統(tǒng)計來幫助分析用戶的使用行為

統(tǒng)計的實現(xiàn)
當(dāng)用戶觸發(fā)一次交互的時候,想向服務(wù)器端發(fā)送一條信息,將其記錄下來,保存在服務(wù)器中。
前端的一些交互,有時候是不需要向服務(wù)器端發(fā)送請求的,此時,服務(wù)器端是不知道這些行為的,所以要向服務(wù)器端發(fā)送請求告知

統(tǒng)計請求方面的考慮
post請求要比get請求發(fā)送的時處理事情要多,在做統(tǒng)計的時候就不考慮post請求
Ajax可以發(fā)送get請求,但是要寫好多邏輯代碼
請求文檔是一個get請求,但是請求過來的頁面中的信息量比較多
script標(biāo)簽也是get請求,
link標(biāo)簽也是一個get請求
img標(biāo)簽也是get請求
相比較這幾種,img的發(fā)送成本更低一些,在發(fā)送統(tǒng)計請求的時候,用img(0字節(jié)的圖片作為中轉(zhuǎn)發(fā)送get請求)的get請求

請求節(jié)流
頁面中的一些高頻事件,做統(tǒng)計的時候,會不停的發(fā)送統(tǒng)計,由于請求的并發(fā)次數(shù)是有限的 ,不能同時發(fā)送這么多的請求。這回造成后面資源的加載延遲,要對這些統(tǒng)計做節(jié)流處理

var img = new Image();
            
function sendLog ( val ) {
    
    var reslutStr = "";
    for ( var i in val ) {
        
        reslutStr += "&" + i + "=" +  val[i];
        
    }
    
    img.src = "a.jpg?" + reslutStr;
    
}

統(tǒng)計的拼接

一條統(tǒng)計 ?Type=click&date=123
將兩條統(tǒng)計拼接在一起 ?Type=click&dat2=123&type=mouseover&date=234,這樣的化出現(xiàn)相同的字段了,不能這么拼接,
可以將一條統(tǒng)計作為一個值: ?Log1=typeclick|date123 //將一條數(shù)據(jù),作為請求的 一個 id.
拼接兩個統(tǒng)計的時候,就可以?Log1=typeclick|date123&log2=typemouserover|date234

//節(jié)流處理: 當(dāng)發(fā)送第一個請求的時候,將其緩存下來,當(dāng)其觸發(fā)的次數(shù)達到規(guī)定的次數(shù)再發(fā)送
//想緩存,需要有緩存容器, dataCache   次數(shù),需要有次數(shù)的規(guī)定。maxNum
//將一條數(shù)據(jù),作為請求的  一個  id.

var LogPack = (function () {
    
    var dataCache = [];  //緩存容器
    
    var maxNum = 10; //緩存的次數(shù)                
    
    var oImg = new Image();  //請求的觸發(fā)器

    var itemSplit = "|";
    var keyValSplit = "*";
    
    //發(fā)送統(tǒng)計
    function sendLog () {
        
        var logs = dataCache.splice(0,10);
        
        var str = "";
        
        for ( var i=0; i maxNum ) {
            
            //發(fā)送
            sendLog();
            
        }
        
    };
    
})()

//觸發(fā)
var oBtn = document.getElementById("btn");

oBtn.onmousemove = function () {
    
    LogPack({
        type: "onmousemove",
        date: new Date().getTime()
    });
    
}
//            
oBtn.onmouseover = function () {
    
    LogPack({
        type: "onmouseover",
        date: new Date().getTime()
    });
    
}

//發(fā)送結(jié)果

MVC 后端的MVC概念

Model(模型)表示應(yīng)用程序核心(比如數(shù)據(jù)庫記錄列表)。
是應(yīng)用程序中用于處理應(yīng)用程序數(shù)據(jù)邏輯的部分。通常模型對象負(fù)責(zé)在數(shù)據(jù)庫中存取數(shù)據(jù)。

View(視圖)顯示數(shù)據(jù)(數(shù)據(jù)庫記錄)。
是應(yīng)用程序中處理數(shù)據(jù)顯示的部分。通常視圖是依據(jù)模型數(shù)據(jù)創(chuàng)建的

Controller(控制器)處理輸入(寫入數(shù)據(jù)庫記錄)
是應(yīng)用程序中處理用戶交互的部分。通常控制器負(fù)責(zé)從視圖讀取數(shù)據(jù),控制用戶輸入,并向模型發(fā)送數(shù)據(jù)。

前端中的實踐

Model,頁面數(shù)據(jù)的存儲操作
View,渲染出可視(給人看)的頁面操作
Controller,頁面的交互對視圖的更改以及對數(shù)據(jù)的更改

View層通過Model渲染數(shù)據(jù),所以View層可以訪問Model層
Controller層可以對Model寫入讀取數(shù)據(jù),所以Controller可以訪問Model層
Controller層可以對View層打開彈層,浮層等交互,所以Controller可以訪問View層

在前端的框架中,很多框架是基于MVC模式實現(xiàn),比如BackBone
它將MVC進行了一些改造,比如它允許Model層可以訪問View層,實現(xiàn)數(shù)據(jù)層的更新通知View層視圖的渲染

通常一個模塊對應(yīng)一個控制器,一個模型,一個視圖,那么如果將頁面所有模塊中的視圖,控制器模型放在一起,邏輯比較混亂,為了管理方便,將一個模塊的控制器,模型,視圖,放在一個文件內(nèi)管理,根據(jù)他們的父模塊不同,來進行分別建立。(父模塊作為建立文件夾的標(biāo)準(zhǔn))

var MVC = {}

//模型模塊
// get 得到模型
// add 添加模型
MVC.Model = (function () { 
    
    //用來存儲數(shù)據(jù)層面的數(shù)據(jù)
    var M = {};
    
    return {
         //讀取數(shù)據(jù)的方法
         //@param {String} strName 讀取數(shù)據(jù)的名稱
         //eg: get("a.b.c") => M.a.b.c
        "get": function ( strName ) {
            
            var path = strName.split(".");
            
            var reslut = M;
            
            for ( var i=0; i           
               
                                           
                       
                 

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/79655.html

相關(guān)文章

  • 深入理解JavaScript

    摘要:深入之繼承的多種方式和優(yōu)缺點深入系列第十五篇,講解各種繼承方式和優(yōu)缺點。對于解釋型語言例如來說,通過詞法分析語法分析語法樹,就可以開始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點 JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點。 寫在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點。 但是注意: 這篇文章更像是筆記,哎,再讓我...

    myeveryheart 評論0 收藏0
  • JavaScript設(shè)計模式與開發(fā)實踐 | 01 - 面向?qū)ο蟮?em>JavaScript

    摘要:在中,并沒有對抽象類和接口的支持。例如,當(dāng)對象需要對象的能力時,可以有選擇地把對象的構(gòu)造器的原型指向?qū)ο螅瑥亩_到繼承的效果。本節(jié)內(nèi)容為設(shè)計模式與開發(fā)實踐第一章筆記。 動態(tài)類型語言 編程語言按數(shù)據(jù)類型大體可以分為兩類:靜態(tài)類型語言與動態(tài)類型語言。 靜態(tài)類型語言在編譯時已確定變量類型,動態(tài)類型語言的變量類型要到程序運行時,待變量被賦值后,才具有某種類型。 而JavaScript是一門典型...

    suxier 評論0 收藏0
  • 理解JavaScript的核心知識點:原型

    摘要:首先,需要來理清一些基礎(chǔ)的計算機編程概念編程哲學(xué)與設(shè)計模式計算機編程理念源自于對現(xiàn)實抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機制一直以來都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因為絕大多數(shù)人沒有想要深刻理解這個機制的內(nèi)涵,以及越來越多的開發(fā)者缺乏計算機編程相關(guān)的基礎(chǔ)知識。對于這樣的開發(fā)者來說 J...

    iKcamp 評論0 收藏0
  • 深入理解Javascript原型關(guān)系

    摘要:如下所示在規(guī)范中,已經(jīng)正式把屬性添加到規(guī)范中也可以通過設(shè)置和獲取對象的原型對象對象之間的關(guān)系可以用下圖來表示但規(guī)范主要介紹了如何利用構(gòu)造函數(shù)去構(gòu)建原型關(guān)系。 前言 在軟件工程中,代碼重用的模式極為重要,因為他們可以顯著地減少軟件開發(fā)的成本。在那些主流的基于類的語言(比如Java,C++)中都是通過繼承(extend)來實現(xiàn)代碼復(fù)用,同時類繼承引入了一套類型規(guī)范。而JavaScript是...

    ethernet 評論0 收藏0
  • JS程序

    摘要:設(shè)計模式是以面向?qū)ο缶幊虨榛A(chǔ)的,的面向?qū)ο缶幊毯蛡鹘y(tǒng)的的面向?qū)ο缶幊逃行┎顒e,這讓我一開始接觸的時候感到十分痛苦,但是這只能靠自己慢慢積累慢慢思考。想繼續(xù)了解設(shè)計模式必須要先搞懂面向?qū)ο缶幊蹋駝t只會讓你自己更痛苦。 JavaScript 中的構(gòu)造函數(shù) 學(xué)習(xí)總結(jié)。知識只有分享才有存在的意義。 是時候替換你的 for 循環(huán)大法了~ 《小分享》JavaScript中數(shù)組的那些迭代方法~ ...

    melody_lql 評論0 收藏0
  • javascript設(shè)計模式與開發(fā)實踐(二)- 封裝和原型模式

    摘要:對象會記住它的原型給對象提供了一個名為的隱藏屬性,某個對象的屬性默認(rèn)會指向它的構(gòu)造器的原型對象,即。我們通過代碼來驗證再來實際上,就是對象跟對象構(gòu)造器的原型聯(lián)系起來的紐帶切記這句話,對未來理解原型鏈很有幫助。 封裝 封裝數(shù)據(jù) 在許多語言的對象系統(tǒng)中,封裝數(shù)據(jù)是由語法解析來實現(xiàn)的,這些語言也許提供了 private、public、protected 等關(guān)鍵字來提供不同的訪問權(quán)限。例如:j...

    luxixing 評論0 收藏0

發(fā)表評論

0條評論

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