Mina <pre>-taggar spiller över lite, så jag ska lösa det på något awesome sätt. Under tiden fungerar piljäveln som ligger uppe till höger för att förstora utrymmet :P
JavaScript har inte, som alla andra vanliga programmeringsspråk, block-level-scope och det är inte alltid tydligt på vad this pekar på. Istället använder sig JavaScript av scope på funktionsnivå, som kan förvirra när man börjar utveckla. För att koka ner det så långt jag kan:
function hello(){
var foo = "bar";
}
hello();
alert(foo); //undefined
Eftersom att foo deklareras inne i funktionen hello() så har inte scopet utanför funktionen möjlighet att se foo. Det är alltså skillnad på lokalt scope och globalt scope (window-objektet).
När man utvecklar plugins för jQuery kan det ibland vara värt att skapa variabler utanför pluginets scope, men ändå dölja det från det globala scopet, för att undvika konflikter, överskrivna variabler och ett onödigt stort window-namespace.
Det enklaste sättet att göra det på är att lägga hela sitt plugin, med de variabler man behöver, i en anonym självanropande funktion.
(function($, window) { //http://antaru.org/self-invoking-functions-i-javascript
//jQuery-plugins
var foo = "bar"; //Variabel som kan kommas åt av alla plugins i scopet
//Plugin utan closure
$.fn.superPlugin = function() {
//Pluginfunktionalitet
};
(function(){
var hurr = "durr"; //Variabel som enbart existerar i det lokala scopet
console.log(foo); //Skriver ut "bar"
//Plugin med closure
$.fn.closurePlugin = function() {
//Pluginfunktionalitet
};
})();
console.log(hurr); //undefined
})(jQuery, this);
Man skulle kunna göra separata “jQuery”-closures för varje plugin, men jag gillar att ha dem samlade och sedan var för sig, om det skulle krävas, ha ett eget closure; sin egna lilla värld.
Att definiera funktioner och globala variabler i JavaScript är oftast ingen bra idé.
Tips till alla Firebug-användare
Kör det här någon gång i början av era scripts:
window.log = function() {
log.history = log.history || [];
log.history.push(arguments);
if (this.console) {
console.log(Array.prototype.slice.call(arguments));
}
};
De som har utvecklat för Firefox och använt Firebugs härliga console.log-funktion, sen testat det i någon annan webbläsare borde känna till problemet när funktionen anropas. Det går sönder. funktionen ovan löser det; plus, om den skapas den direkt kan man anropa log-metoden precis när som helst, och det går inte sönder, även om man råkar släppa koden skarpt.
Scriptet hittade jag på Paul Irish hemsida.
Edit: Testade lite mer, och att kunna anropa log.history i firebug är faktiskt riktigt sweet.