全局變量是魔鬼,這句話在JavaScript存在的地方應(yīng)該就是成立的,當(dāng)然Firefox擴(kuò)展也不例外,如果大家把多于一個(gè)的對(duì)象置于全局命名空間下,和其他擴(kuò)展的沖突是很容易發(fā)生的,而且發(fā)現(xiàn)這種沖突引起的錯(cuò)誤是很困難的,因?yàn)槊總(gè)人的擴(kuò)展列表都不一樣啊。避免全局名字污染已經(jīng)成了一個(gè)基本原則,本文從這點(diǎn)引申,介紹了一個(gè)應(yīng)用在Firebug中的擴(kuò)展架構(gòu)模式,非常值得推薦。
【原文】Firefox Extensions: Global Namespace Pollution 【作者】Jan Odvarko 【譯文】http://cuimingda.com/2009/01/ 【譯者】明達(dá)
以下是對(duì)原文的翻譯:
最近有幾個(gè)開發(fā)者向我咨詢?nèi)绾卧O(shè)計(jì)Firefox擴(kuò)展的架構(gòu),第一個(gè)顯現(xiàn)在我腦海中的答案就是要合理定義那些在ChromeWindow作用域下的全局變量。
不合理的定義全局變量,可以輕易的引發(fā)不同擴(kuò)展之間的沖突,而這些完全是應(yīng)該避免的(這也是AMO審閱的步驟之一),因?yàn)闆_突所引發(fā)的問(wèn)題是很難被發(fā)現(xiàn)的。就目前的開發(fā)環(huán)境來(lái)說(shuō),全局變量就是魔鬼,尤其是采用OOP開發(fā)模式的時(shí)候。
我不想重復(fù)介紹如何從頭開始開發(fā)一個(gè)Firefox擴(kuò)展,對(duì)于這方面已經(jīng)有很多非常詳細(xì)的文章。本文的重點(diǎn)放在如何設(shè)計(jì)一個(gè)更加易于維護(hù)的Firefox擴(kuò)展架構(gòu)。
如果你對(duì)前面的介紹感興趣,那就接著看吧。。。
命名空間架構(gòu)
擴(kuò)展之間發(fā)生沖突的重要原因就是因?yàn)槎x了不合理的全局變量。我認(rèn)為對(duì)每個(gè)擴(kuò)展來(lái)說(shuō),只有一個(gè)全局變量已經(jīng)很足夠了(可以根據(jù)擴(kuò)展的信息來(lái)定義這個(gè)唯一的全局變量的名字,比如可以是擴(kuò)展的名字、域名、地址等),不僅可以滿足我們的開發(fā),而且可以避免那些令人討厭的沖突。
Firebug使用的命名空間架構(gòu),基本建立在著名的Module Pattern基礎(chǔ)上(這種模式最早由Douglas Crockfod定義)下的。這種模式簡(jiǎn)單而清晰,但其實(shí)我在很長(zhǎng)時(shí)間里都不是很明確這種模式究竟是如何工作的(I hadn’t understand how it actually works for a long time)。我相信每個(gè)開發(fā)者都可以充分利用這個(gè)方法。
基本的思路是將每個(gè)JavaScript腳本文件放進(jìn)自己的作用域,這是通過(guò)一個(gè)函數(shù)來(lái)實(shí)現(xiàn)的,沒有定義任何全局變量,比如下面這段代碼:
function() { // TODO: 腳本文件中的全部代碼 }
我管這個(gè)函數(shù)就叫做命名空間。擺在眼前的第一個(gè)問(wèn)題是,如何確定這個(gè)函數(shù)的內(nèi)容會(huì)在正確的時(shí)間被調(diào)用。第二個(gè)問(wèn)題是,如何在多個(gè)腳本文件中共享對(duì)象(這個(gè)會(huì)在后面的章節(jié)解答)。 Firebug通過(guò)將所有的命名空間進(jìn)行注冊(cè),并在Firefox chrome UI加載的時(shí)候調(diào)用來(lái)解決第一個(gè)問(wèn)題,也就是下面這段代碼:
myExtension.ns(function() { // TODO: 腳本文件中的全部代碼 });
命名空間(就是原來(lái)定義的那個(gè)函數(shù))為當(dāng)作myExtension.ns函數(shù)的一個(gè)參數(shù),而myExtension對(duì)象是這個(gè)擴(kuò)展中定義的唯一全局變量。這個(gè)對(duì)象代表著整個(gè)擴(kuò)展。不用擔(dān)心這個(gè)名字太長(zhǎng),我們可以為他建立個(gè)快捷方式(在實(shí)際開發(fā)中,這個(gè)名字可能會(huì)類似 comSoftwareIsHardMyExtension這個(gè)樣子)。
ns函數(shù)比較簡(jiǎn)單,就是把所有的方法都添加到一個(gè)數(shù)組中。
var namespaces = []; this.ns = function(fn) { var ns = {}; namespaces.push(fn, ns); return ns; };
執(zhí)行已注冊(cè)命名空間的函數(shù),不可以命名為apply,別的什么名字都可以。
this.initialize = function() { for (var i = 0; i < namespaces.length; i += 2) { var fn = namespaces[i]; var ns = namespaces[i + 1]; fn.apply(ns); }};
現(xiàn)在,然我們把前面的代碼連起來(lái),看看全局?jǐn)U展對(duì)象是如何定義和初始化的。
出處:七月佑安
責(zé)任編輯:bluehearts
上一頁(yè) 下一頁(yè) Firefox擴(kuò)展的全局命名空間污染 [2
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|