2011-03-29 64 views
11

我正在開發一個項目,我真的想編寫面向對象的JavaScript代碼。我剛開始閱讀Douglas Crockford's JavaScript: The Good Parts,我很快就意識到在JavaScript中編寫Java-esque OOP將是一項艱鉅的任務。JavaScript中的Java-esque OOP和jQuery失敗

到目前爲止,我已經寫了類似如下的...

// index.html 
$(document).ready(function() { 

    $().SetUpElements(); 
}); 

// this is in a different js file 
$.fn.SetUpElements = function() { 

    // do stuff here 
    $().UpdateElement(); 
}; 

// this is in yet another different js file 
$.fn.UpdateElement = function() { 

    // do stuff here 
    var element = new Element(id, name); // continue doing work 
}; 

function Element(id, name) { 

    var id = id; 
    var name = name; 

    // other stuff 
}; 

...的想法是,我希望對象/函數進行重構和脫鉤儘可能多地;我想盡可能多地重複使用代碼。我已經將很多代碼分佈在不同的.js文件中,旨在將特定的相關代碼分組在一起,就像您將使用Java編寫不同的類一樣。

由於我已經瞭解了更多關於jQuery的知識,我意識到$.fn.foo = function() { ... };這個符號實際上是將這個foo函數添加到所有jQuery對象的原型中。這是我應該做的事嗎?我以某種方式濫用jQuery?

我將不勝感激關於如何改進我在JavaScript中使用面向對象的方法的建議,我很樂意看到有關源/教程/文章/等的參考資料......討論此主題。即使選擇了答案,也請隨時提供反饋意見。我正在尋找你的建議......這就是我發佈的原因:)

**注意:我沒有開發jQuery插件。我正在開發一個Web應用程序,並大量使用jQuery。

+0

查看require.js來處理大中型項目的文件加載和依賴項。 – Raynos 2011-04-01 15:27:26

+0

@Raynos ...絕對會看看。是類似http://headjs.com/ – Hristo 2011-04-01 15:35:39

回答

3

我會說你創建方法的第一種方式是濫用jQuery。 jQuery.fn.foo語法通常保留給作用於DOM元素但通過使用空的jQuery對象使用它們作爲靜態函數的函數。

如果你想在jQuery的命名空間下創建靜態函數,你可以這樣做:的

jQuery.foo(); 

代替:

jQuery.foo = function(){}; 

然後通過調用它

jQuery.fn.foo = function(){}; 

這允許你這樣做:

jQuery('#someElementId').foo(); 

就OOP而言。有很多不同的方法(模塊模式,原型,工廠...)。我一般路徑選擇,就是創建一個類的靜態函數,然後用關鍵字new

(function($){ 
    var undefined; 

    $.ClassName = function(options){ 
     var self = this; 
     var cfg = $.extend(true, {}, this.defaults, options); 

     // ******************** 
     // start:private 
     // ******************** 
     function _init(){ 

     }; 

     // ******************** 
     // start:public 
     // ******************** 
     this.methodName = function(){ 

     }; 

     _init(); 
    }; 

    $.ClassName.prototype.defaults = {}; 
})(jQuery); 

調用它在重複使用功能方面,有一個門檻之後去耦比什麼都不利。確保您保持模塊化和組織的正確平衡。

+0

@alex ...這看起來不錯,謝謝!你寫的與其他用戶所建議的「命名空間」概念有什麼不同? – Hristo 2011-03-29 20:10:33

+0

@Hristo嗯,實際上我只是把它放入jQuery命名空間。這裏的大多數人建議反對它,所以我的代碼可以很容易地更改爲YOURNAMESPACE.ClassName = function(){} – 2011-03-29 20:19:38

+0

@alex ... ohhh好吧,我明白了。 – Hristo 2011-03-29 20:22:25

1

如果您正在開發插件,通常最好儘可能避免污染jQuery和Global命名空間/原型。

看看this documentation on jQuery's website,它給出瞭如何提供對各種可重用功能的訪問的絕佳解釋,同時只聲明jQuery對象上的單個名稱。

我見過的另一種方法是爲jQuery名稱空間上的插件提供一個init函數,然後在Global名稱空間中提供一個額外的插件專用名稱,該名稱提供了對函數的更直接訪問/會員等Galleria plug-in是如何做到這一點很好的例子。檢查他們的文檔,以及他們設置插件結構的方式。

編輯

看到,你是不是製作一個插件後:很多的,我說仍適用於一般的jQuery開發的東西(真的,到總體的發展)。

在您的具體情況中,由於您沒有在進行函數調用時使用jQuery選擇器,因此這些函數可能很容易附加到您自己製作的原型上,這些原型可放置在全局名稱空間。

至於命名空間去,看看接受的答案對這個問題對於如何正確地做到這一點的例子:How do I declare a namespace in JavaScript?

這裏是在JavaScript OO一個很好的資源。我用這篇文章試圖環繞的概念,我的頭的時候:http://mckoss.com/jscript/object.htm

+0

@恩德... 1.我愛你的名字:) 2.我**不**開發插件。 – Hristo 2011-03-29 19:52:04

+0

@Ender ...感謝您的「編輯」。這是我想要介紹的方向。現在,我已經看到了對「命名空間」的這種引用兩次......那是什麼?如何/在哪裏可以瞭解更多關於創建自己的名稱空間的信息? – Hristo 2011-03-29 20:01:55

+0

我剛剛添加了對另一個SO問題的引用*希望*會回答這個問題:) – Ender 2011-03-29 20:02:28

4

在參考在Javascript做OO你應該看Douglas Crockford's Advanced Javascript lessons

+0

@mlaw ...我實際上開始閱讀他的書「JavaScript - 好的部分」。我一定會看看課程。謝謝! – Hristo 2011-03-29 20:00:41

+0

這些視頻比本書更具信息量。雖然我會提到另一本書的強制性參考 - JavaScript:權威指南(http://www.amazon.com/JavaScript-Definitive-Guide-David-Flanagan/dp/0596101996/ref=sr_1_2?ie=UTF8&qid= 1301429052&SR = 8-2)。 – 2011-03-29 20:04:34

0

看起來你正在編寫所有的代碼爲jQuery插件?我不會那樣做。創建你自己的名字空間。

將所有內容放入不同文件的目標是什麼?除非它們是用於特定頁面的腳本,否則這會使事情管理變得更加困難。這些都看起來像通用庫函數。除非你認爲你想在一個頁面上加載一些,但不是全部,然後把它們全部放在一個文件中。

面向對象的編程並不意味着跨文件分割東西。這只是組織,當你不需要某些頁面上的所有內容時,你應該把事情分解成不同的文件。

+0

@jamietre ...嗯...這讓人很有道理!我不是想寫一個插件,所以我看到我的錯誤在哪裏。我在文件之間傳播東西的原因是,我可以將特定功能組合在一起並輕鬆定位,這樣我就不必滾動瀏覽一個巨型文件。 你是什麼意思「創建你自己的命名空間」?你能提供一個解釋/來源/鏈接/等...? – Hristo 2011-03-29 20:00:04

6

如果它不是一個jQuery插件,我會寫這樣的事:

var app = { 
     init: function(){ 
     app.SetUpElements(); 
     }, 
     SetUpElements: function() { 
     return 'something'; 
     }, 
     etc: function() { 

     } 
    }; 
    $(document).ready(app.init); 
+0

@minibikini ...變量'app'代表什麼? – Hristo 2011-03-29 20:04:47

+0

這是@jamietre的意思是「設置你自己的名字空間」。 'app'是你的命名空間的全局對象,它將包含你的分組函數和屬性。 'app'應該是一個非常獨特的應用程序名稱,因爲它是您的主要全局對象。 – mVChr 2011-03-29 20:05:22

+0

@mVChr ...真棒,謝謝! – Hristo 2011-03-29 20:08:43

0

由於大部分已經提到過,除非你明確地創建一個公共插件,不使用jQuery自定義函數。相反,請使用簡單的對象表示法創建自己的名稱空間,或者更類似Module Pattern的其他類型。如果你想變得瘋狂,你可以使用API​​上的API來使用Dean Edward's Base來獲得更經典的OO模式。最終目標是從jQuery API中提取您的功能和設計要求。這樣,如果您需要將某些東西移植到Mootools或Prototype,那麼完成起來會更簡單。

+0

@ hal10001 ...你能提供關於創建命名空間的更多信息嗎?這實際上是我第一次聽說這個術語:/ – Hristo 2011-03-29 20:06:01