這一篇主要講述構造器(Constructor)模式和模塊(Module)模式以及相關的變體模式,例子是JavaScript代碼。 構造器(Constructor)模式 對象構造器用於創建特定類型的對象——準備好對象以備使用,同時接收構造器可以使用的參數,以在第一次創建對象時,設置成員屬性和方法的值。 ...
這一篇主要講述構造器(Constructor)模式和模塊(Module)模式以及相關的變體模式,例子是JavaScript代碼。
構造器(Constructor)模式
對象構造器用於創建特定類型的對象——準備好對象以備使用,同時接收構造器可以使用的參數,以在第一次創建對象時,設置成員屬性和方法的值。概念並沒什麼好說的,這種模式最是簡單,雖然名字是那麼弔炸天,但內容沒什麼,看下麵例子就可明白。
基本構造器
function Car( model, year, miles ) { this.model = model; this.year = year; this.miles = miles; this.toString = function () { return this.model + " has done " + this.miles + " miles"; }; } // Usage: // We can create new instances of the car var civic = new Car( "Honda Civic", 2009, 20000 ); var mondeo = new Car( "Ford Mondeo", 2010, 5000 ); // and then open our browser console to view the // output of the toString() method being called on // these objects console.log( civic.toString() ); console.log( mondeo.toString() );
PS:類與對象實例效果圖。
帶原型的構造器
function Car( model, year, miles ) { this.model = model; this.year = year; this.miles = miles; } // Note here that we are using Object.prototype.newMethod rather than // Object.prototype so as to avoid redefining the prototype object Car.prototype.toString = function () { return this.model + " has done " + this.miles + " miles"; }; // Usage: var civic = new Car( "Honda Civic", 2009, 20000 ); var mondeo = new Car( "Ford Mondeo", 2010, 5000 ); console.log( civic.toString() ); console.log( mondeo.toString() );
PS:類與對象實例效果圖。
兩者區別
這兩個示例區別就在於toString方法的定義。前一個例子每一個實例都各自重新定義這種方法;後一個例子使用原型定義方式,使得這種方法在所有的Car實例之間共用,好處在於,共用函數能夠減少記憶體消耗(我認為),優化代碼。
這裡需要註意幾件事:
1. 函數才有prototype屬性,指向的是一個實例對象(不是函數)。
2. 每個實例對象都有__proto__的屬性,這個屬性指向原函數所指的原型對象(原型繼承的基礎)。
模塊(Module)模式
模塊模式是為類提供私有變數和特權方法(有權訪問私有變數和私有函數的公有方法)的方法。在JavaScript,就可通過閉包的方式,模擬實現模塊模式。
對象字面量:
var myModule = { variableKey: variableValue, getKey: function () { // ... } };
嚴格上講,對象字面量實現的只是不完整的模塊模式,因為無法達到變數、方法私有效果。不過確實有分離和組織代碼的能力,也就算一種簡略的模塊模式的實現方式。
簡單例子:
var myModule = (function(){ var privateVar = 10; return { getPrivateVar : function(){ return privateVar; } } })();
引入全局變數例子:
// Global module var myModule = (function ( jQ, _ ) { function privateMethod1(){ jQ(".container").html("test"); } function privateMethod2(){ console.log( _.min([10, 5, 100, 2, 1000]) ); } return{ publicMethod: function(){ privateMethod1(); } }; // Pull in jQuery and Underscore })( jQuery, _ );
PS:書中還有相應結合Dojo、ExtJS、YUI、jQuery等框架的模塊模式的實現方式,不過我覺得只要理解模塊模式的就行了,也不一一列例子。
揭示(Revealling)模塊模式
這種是模塊模式的改進版本,它是在模塊代碼底部,定義所有對外公佈的函數(僅是指針)和變數。
var myRevealingModule = (function () { var privateVar = "Ben Cherry", publicVar = "Hey there!"; function privateFunction() { console.log( "Name:" + privateVar ); } function publicSetName( strName ) { privateVar = strName; } function publicGetName() { privateFunction(); } // Reveal public pointers to // private functions and properties return { setName: publicSetName, greeting: publicVar, getName: publicGetName }; })();
這種模式我經常使用,它很容易指出哪些函數和變數可以被公開訪問,增強了可讀性。
總結
有時我們在不經意間就使用了某種模式(例如上面兩種模式),但並不知道寫的東西已經是前人總結很好的東西了。所以在細細閱讀過程中,書中內容使得我自己對模式的認識更加系統全面,也能改正自己使用上的誤區。
參考文獻
1. 《Learning JavaScript Design Patterns》 by Addy Osmani
https://addyosmani.com/resources/essentialjsdesignpatterns/book/
2. 《JavaScript設計模式》by 徐濤【譯】
本文為原創文章,轉載請保留原出處,方便溯源,如有錯誤地方,謝謝指正。
本文地址 :http://www.cnblogs.com/lovesong/p/5572568.html