原文連接:My Favorite JavaScript Design Pattern
譯文原鏈:【譯】我最喜歡的 JavaScript 設計模式javascript
我以爲聊一下我愛用的 JavaScript 設計模式應該頗有意思。我是一步一步才定下來的,通過一段時間從各類來源吸取和適應直到達到一個能提供我所需的靈活性的模式。java
讓我給你看看概覽,而後再來看它是怎麼造成的:設計模式
function MyScript(){} (function() { var THIS = this; function defined(x) { return typeof x != 'undefined'; } this.ready = false; this.init = function( { this.ready = true; }; this.doSomething = function() { }; var options = { x : 123, y : 'abc' }; this.define = function(key, value) { if(defined(options[key])) { options[key] = value; } }; }).apply(MyScript);
如你在實例代碼中看到的,總體框架是一個函數直接量(function literal):閉包
(function() { ... })();
函數直接量基本上就是一個自執行域,至關於定義一個有名的函數而後當即調用它:app
function doSomething() { ... } doSomething();
我最初開始使用函數直接量是爲了封裝
——任何格式的任何腳本均可以被封裝在那個閉包裏,而且它有效地將它密封
在私有域中,從而保護它不會與同一個域裏的其它腳本或者數據衝突。在最後面的那一對括號就是在執行這個域,就像其它函數同樣調用它。框架
可是若是,這個域經過使用 Function.apply
來執行而不是全局調用,這可讓它在一個可被外界引用的特定命名的域中執行。函數
所以經過結合兩者——建立一個命名函數,而後在這個命名函數的域內執行一個函數直接量——咱們就獲得了一個一次性的能夠構成任何腳本的基礎的對象,它模擬了相似面向對象類的繼承性質。this
看看第一個代碼示例,你就能看到封閉域結構提供了什麼樣的靈活性。固然,這些你均可以在任何方法中作到,可是經過用這種方式包裝起來,咱們就有了一個能夠和任何命名域聯繫起來的結構體。設計
咱們能夠建立多個這樣的結構體,而後將它們和同一個域聯繫起來,這樣它們之間所有能夠共享它們的公開數據。code
不過在共享公開數據的同事,每個(結構體)也能夠定義它本身的私有數據。下面是一個例子,在腳本的最上面:
var THIS = this;
咱們建立了一個叫作 THIS
的私有變量,它指向這個函數域,而且能夠在私有方法中使用——和用 self = this
來建立內部域是同樣的招數。
經過一樣方式聲明的其餘私有變量,若是他們定義常量數據的話,可使用大寫傳統(不過用 const
而不是 var
來作聲明的方式應該被避免,由於對它的支持不是很好)。
私有方法能夠用來提供內部功能:
function defined(x) { return typeof x != 'undefined'; }
而後咱們能夠建立其餘實例或者外界能夠訪問的公開方法和屬性:
this.ready = false; this.init = function() { this.ready = true; }; this.doSomething = function() { };
咱們也能夠建立特殊的值——私有可是能夠公開定義,在這個例子中是經過公開的 define
方法;它的參數能夠根據數據須要再進行驗證:
var options = { x : 123, y : 'abc' }; this.define = function(key, value) { if(defined(options[key])) { options[key] = value; } };
全部的這些特色讓這個結構體對我很是有用。而且它封裝在一個整潔、自我執行的單例中——一個容易引用、整合和使用的一次性對象。
因此你怎麼想?這個模式眼熟嗎,或者你有什麼其餘喜歡用的?