javascript - Hur kan en Firefox-tillägg bäst undvika att förorena det globala namnområdet?
Jag har läst på om globalt namnrymdsförorening när jag utvecklar ett tillägg för Firefox, och jag vill undvika det så mycket som möjligt i mitt tillägg. Det finns flera lösningar, men generellt verkar lösningarna handla om att bara deklarera en global variabel för ditt tillägg och lägga allt i den. På så sätt lägger du bara till en extra variabel i den globala namnrymden, vilket inte är så illa.
Som en kort sidonotering har man föreslagit en lösning för mig som undviker att lägga in några extra variabler i det globala namnområdet; slå in allt i en funktion. Problemet här är att det inte finns något att referera till i dina XUL-överläggningar. Du måste deklarera element i dina överläggningar, och sedan i JS lägga till en massa addEventListener för att ersätta det som annars skulle ha varit något som oncommand="..." i XUL. Jag vill inte göra detta; jag vill definitivt att mitt XUL ska inkludera händelser i själva XUL eftersom jag tycker att det ser renare ut, så detta är ingen lösning för mig. Jag behöver därför åtminstone 1 global variabel för XUL oncommand="..."-attribut att referera till.
Så konsensus verkar vara att ha en (och endast en) variabel för din extension, och lägga all din kod i den. Här är problemet: generellt rekommenderar folk att den variabeln bör ha ett långt, unikt namn för att ha nästan noll chans att krocka med andra variabler. Så om min extensions ID är [email , skulle jag kunna namnge min variabel myextensionAtMycompanyDotCom, eller com.mycompany.myextension. Detta är bra för att undvika krockar i det globala namnområdet, men det finns ett problem; det variabelnamnet är långt och klumpigt. Min XUL kommer att vara full av referenser till händelsehanterare i stil med oncommand="myextensionAtMycompanyDotCom.doSomeEvent". Det finns inget sätt att undvika att behöva referera till det globala namnområdet i mina XUL-overlays, eftersom ett overlay bara läggs till i webbläsarfönstrets DOM; det har inget eget namnområde, så vi kan inte på något sätt begränsa vår extensions variabelomfång till endast våra egna overlays. Så, som jag ser det, finns det fyra lösningar:
1. Använd bara det långa variabelnamnet i XUL
Detta resulterar i ganska ohanterlig, omständlig XUL-kod som:
<statusbarpanel id="myStatusBar" onmousedown="myextensionAtMycompanyDotCom.onMyStatusBarClick();">
2. Lägg till ett inslag av slumpmässighet till ett kort variabelnamn
Vi kommer på ett mycket trevligare kort variabelnamn för vår förlängning, låt oss säga myExt, och lägger till några slumpmässiga tecken för att göra det nästan säkert unikt, till exempel myExtAX8T9. Sedan i XUL har vi:
<statusbarpanel id="myStatusBar" onmousedown="myExtAX8T9.onMyStatusBarClick();">
Tydligt resulterar detta i ganska ful och till och med förvirrande kod eftersom de slumpmässiga tecknen ser konstiga ut och får det att se ut som någon slags tillfällig variabel.
3. Deklarera inga globala variabler alls
Du skulle kunna bara kapsla in allt i funktioner. Detta betyder naturligtvis att det inte finns något att referera till i din XUL, och därför måste varje händelse kopplas till XUL-elementen med addEventListener i din JavaScript-kod. Jag tycker inte om denna lösning eftersom, som nämnts ovan, jag tycker att det är renare att ha händelserna refererade i XUL-koden istället för att behöva söka igenom en massa JS-kod för att hitta vilka händelser som är kopplade till vilka XUL-element.
4. Använd bara ett kort variabelnamn i XUL
Jag skulle bara kunna kalla min förlängnings variabel myExt, och då får jag snygg XUL-kod som:
<statusbarpanel id="myStatusBar" onmousedown="myExt.onMyStatusBarClick();">
Självklart är detta korta namn mycket mer sannolikt att krocka med något annat i det globala namnområdet och är därför inte idealiskt.
Så, har jag missat något? Finns det något alternativ till de 4 lösningar jag föreslog ovan? Om inte, vilken skulle vara den bästa av de 4 (med tanke på att #3 i princip är oacceptabel för mig), och varför?
Svar #1
Vi använder JavaScript-modulmönstret som beskrivs i detta blogginlägg: http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth. Du kan exportera de symboler som du vill använda i dina XUL-hanterare som beskrivs.
Dessutom använder vi ett omvänt värdnamn som prefix för modulnamnet för att säkerställa att vi kontrollerar namnutrymmet:
/* Set up the global namespace. */
if (typeof(com) == "undefined") var com = {};
if (!com.salsitasoft) com.salsitasoft = {};
/* Main namespace. */
com.salsitasoft.myExtensionGlobalStuffGoesHere = (function (my) {
return my;
})(com.salsitasoft.myExtensionGlobalStuffGoesHere || {});
Uppdatering: Jag ändrade detta för att skicka com.salsitasoft.myExtensionGlobalStuffGoesHere in i stängningen om det redan finns, så att namnområdet kan spridas över flera filer.
Svar #2
Dina funktioner måste "leva" någonstans oavsett, så du kan inte undvika att kräva någon form av namnrymd. Jag håller också med din poäng att det är bättre att definiera händelsen i XUL än att fästa dem. Så jag föreslår en hybrid mellan 3+4:
- Hitta ett namnrum som är unikt för din plugin men ändå så lockande som möjligt, till exempel "catchyseo".
Placera all kod för ditt plugin och alla variabler inom detta namnrymd. Använd mönstret med anonym funktionsomslag som (titta på några jQuery-plugins som kodexempel):
window.catchyseo = (function(){var private = x; [...] })();I ditt namnrymd, exponera några händelsehanterare som du kan referera till i din XUL.
Detta tillvägagångssätt ger dig det bästa av två världar: du kan definiera dina händelser i XUL och du har ett stängt namnrymd utan någon global namnrymdsförorening - förutom din enda namnrymdsvariabel.
