1. 程式人生 > >設計模式---- 單例模式 工廠模式 建構函式模式 原型模式 混合模式

設計模式---- 單例模式 工廠模式 建構函式模式 原型模式 混合模式

單例模式

把描述同一個事物(同一個物件)的屬性和方法放在一個記憶體空間下,起到分組的作用,這樣不同事物之間的屬性即使屬性名相同,相互之間也不會衝突。
在專案中可以使用單例模式來進行模組化開發。

var person1 = {
    name:'jack',
    age:18
};

var person2 = {
    name:'tom',
    age:18
};

弊端:雖然起到了分組的作用,但是不能實現批量生產,屬於手工作業模式。

工廠模式

把實現同一件事情的相同的程式碼放到一個函式中,以後如果再次實現這個功能就不需要重新編寫新的程式碼了,只需要執行當前的函式即可。我們把工廠模式成為“函式的封裝”(低耦合高內聚:減少頁面中的冗餘程式碼,提高程式碼的重複利用率。)
function createPerson(name,age){
    var obj = {};
    obj.name = name;
    obj.age = age;
    obj.say = function(){
        console.log(this.name + '---' + this.age)
    }
    return obj;
}
var person1 = createPerson('jack',18);
var person2 = createPerson('tom',28);

建構函式模式

 function createPerson(name,age){
     this.name = name;
     this.age = age;
     this.say = function(){
        console.log(this.name + '---' + this.age)
    }
 }
 var person1 = new createPerson('jack',18);
 var person2 = new createPerson('tom',28);

建構函式模式和工廠模式的區別:
1.執行的時候:
    普通函式:createPerson()
    建構函式:new createPerson() 通過new執行後,createPerson就是一個類了。而函式的返回值就是這個類的一個例項。
                     JS當中所有的類都是function資料型別,它通過new執行變成了一個類,但是它本身也是一個普通的函式。
                     JS當中所有的例項都是Object資料型別的。
2.在函式程式碼執行的時候:
相同點:都是形成一個私有的作用域,然後形參賦值--->預解釋--->程式碼從上到下執行(類和普通函式一樣,也有普通的一面)
不同點:在程式碼執行之前,不用自己再手動的建立物件了,瀏覽器會預設建立一個物件資料型別的值(這個物件就是當前類的一個例項),接下來程式碼從上到下執行,以當前例項為執行的主體(this代表的就是當前的主體),分別把屬性名和屬性值賦值給當前的例項,最後瀏覽器會預設的把建立的例項返回。

** 在建構函式模式中,類中(函式體中)出現的this.xxx=xxx中的this指的是new出來的當前例項。
** 雖然通過這個類例項化出來的物件都擁有相同名稱的方法,但是不同例項之間的方法是不一樣的。
** 在建構函式中 new Fn()執行,如果不需要傳遞引數,後面的小括號可以省略。
** 在類中出現的出現的this.xxx=xxx中的this指的是類的當前例項。而某一個屬性值(方法)中的this需要看方法執行的時候,前面是否有‘.’才能知道this是誰。
** 類有普通函式的一面,在類中var出來的變數只是當前形成的私有作用域中的私有變數而已,它和例項沒有任何關係,只有this.xxx=xxx才和例項有關係。
** 在建構函式中瀏覽器會預設的把例項返回(返回的是一個物件資料型別的值);如果手動return:
    如果返回的是基本型別的值,當前例項是不變的;
    如果返回的是引用資料型別的值,當前的例項會被自定義返回的值替換掉。

原型模式

基於建構函式模式的原型模式解決了方法或屬性公有的問題,把例項之間相同的屬性和方法提取成公有的屬性和方法,想讓誰公有就把他放到建構函式的prototype上即可。
** 每一個函式資料型別(普通函式和類)都有個天生自帶的屬性:prototype,並且這個屬性是一個物件資料型別的值。
** 並且在prototype上瀏覽器天生給它加了一個屬性:constructor(建構函式),屬性值是當前函式(類)本身。
** 每一個物件資料型別(普通物件、例項、prototype)也天生自帶一個屬性:__proto__,屬性值是當前例項所屬類的原型(prototype)。

 Object是Js中所有物件資料型別的基類(最頂層的類); 
A) F1 instanceof Object 結果是true,因為f1通過__proto__可以向上級查詢,不管多少級最後總能找到object
B) 在object.prototype上沒有__proto__;
原型鏈:過 物件名.屬性名 的方式獲取屬性值的時候,首先在物件的私有屬性上查詢,如果私有中存在這個屬性,則獲取私有屬性;如果私有沒有,則通過__proto__找到所屬類的原型(類的原型上定義的屬性和方法都是當前例項公有的屬性和方法),原型上存在,獲取的是公有的屬性值;如果原型上也沒有。則繼續通過原型上的__proto__繼續向上查詢,一直查詢到Object.prototype,如果還沒有就返回undefined;

混合模式

混合模式是建構函式和原型模式的結合,它的優勢是可以將公有的方法和屬性放在原型上,將物件自身的可變的私有屬性放在建構函式上,在使用的時候不管建立多少個例項,他們之間公有的方法只佔用一份記憶體。只有私有的屬性和方法才會另外開闢一份記憶體。節省了記憶體的使用。

  function createPerson(name,age){
     this.name = name;
     this.age = age;
     this.say = function(){
        console.log(this.name + '---' + this.age)
    }
 }
createPerson.prototype = {
        write:function(){console.log('write')}  //例項公有
}