Skrivet av DiAMONDBACK:
Japp, gjorde detta istället. Logiken blev mycket tydligare för mig.
Men jag ska anstränga mig för att lära mig mer om anonyma funktioner
När vi ändå är här så skulle jag vilja ytterligare faktorera om koden en smula:
// Elementväljare
var getCel = document.getElementById("databox");
var sendCel = document.getElementById("celcius");
// Metoder
function convertFahr() {
var inData = getCel.value;
var conversion = inData * (9/5) + 32;
alert(conversion);
}
// Händelser
sendCel.addEventListener('click', convertFahr);
Jag har inte gjort mycket, men jag har flyttat ut elementväljarkoden `document.getElementById("databox")` utanför funktionen. När denna kod körs så går webbläsaren igenom sidans struktur ("DOM-träd") och letar upp detta element. Eftersom elementet är samma oavsett hur många gånger du kallar på funktionen så är det onödigt att inuti funktionen varje gång leta reda på fältet i DOM-trädet. Genom att lägga det utanför så görs detta en enda gång, och kanske framför allt så strukturerar vi upp koden i tre tydliga delar (som jag också markerat med kommentarer i koden för övertydlighets skull ):
elementväljare
metoder
händelser
där jag också ändrat ordning på de sista två i koden för att få saker mer logiskt följande.
"Tricket" med att använda en anonym funktion som callback till `addEventListener` är faktiskt lite av en styggelse, skulle jag säga. Det uppmanar till dålig separation av distinkta områden i koden. Dessutom gör det ju saker som återanvändning av kod problematisk, och det frestar lätt en programmerare till att kopiera och klistra från den icke-återanvändningsbara koden i den anonyma funktionen snarare än att skriva funktioner på en centraliserad plats där man kanske även kan abstrahera gemensamma delar ytterligare ett steg. Som ett ytterligare argument så kan det vara hjälpsamt (åtminstone inte sämre) för debuggning att separara kod bättre.
Det kan nämnas att på grund av hur `addEventListener` är uppbyggd så kan man ibland vara tvungen att använda en intermediär anonym funktion för att skicka med argument till en lyssnare, men ofta (alltid?) går det att faktorera på andra sätt, och dessutom går det alltid att låta denna intermediära funktion vara ett minimalt anrop så att man i vilket fall sköter logiken i en separat sektion.
Ytterligare mindre notiser:
När `addEventListener` kallar på en lyssnare (dvs när händelsen triggats) så skickas det automatiskt med ett "händelse"-argument. Vi kan förtydliga och fånga detta genom att lägga till ett inargument till `convertFahr()`. Vi använder det inte här, men det är ett bra idiom att ta med sig.
`convertFahr()` låter som en funktion som konverterar till Fahrenheit — men den överraskar lite eftersom den även tar data från ett visst fält och slänger upp en `alert`-ruta. Jag skulle konceptuellt vilja separera dessa steg, så att `convertFahr()` verkligen bara tar ett Celsiusgradantal som inargument och ger tillbaka ett Fahrenheitgradantal. Funktionen som presenterar saker kan heta något annat.
Funktionsnamn — det finns ofta väldigt liten anledning att förkorta och göra saker mindre direkt läsbara. Varför `convertFahr` och inte `convertFahrenheit`? Eller `convertToFahrenheit`? Eller `convertCelsiusToFahrenheit` (för funktionen konverterar ju inte exempelvis Kelvin)? Eller kanske bara `celsiusToFahrenheit`, för "verbet" känns rätt inbakat då.
Med dessa ändringar får vi:
// Elementväljare
var celsius = document.getElementById('databox'); // "databox" är inte ett så beskrivande namn; tänk ut något bättre.
var convert = document.getElementById('celcius'); // Ändra stavningen på objekt-ID ;-) .
// Metoder
function celsiusToFahrenheit(degreeCelsius) {
return degreeCelsius * 9/5 + 32;
}
function presentFahrenheit(event) {
var degreeCelsius = celsius.value;
var degreeFahrenheit = celsiusToFahrenheit(degreeCelsius);
alert(degreeFahrenheit);
}
// Händelser
convert.addEventListener('click', presentFahrenheit);
Variabelnamnen är inte "perfekta", men det kan vara en poäng i att lämna lite frågor att fundera på själv. Är `celsius` och `convert` bra namn på elementen? Är det logiskt att knappen som konverterar till Fahrenheit heter "celcius" (sic)? Varför/varför inte? Varför blandade originalkoden 'strängar' och "strängar" — är det någon skillnad på apostrofer och citationstecken när strängar definieras? Spelar det någon roll här? Etc.
En annan sak att ta med sig är att det "i verkligheten" oftast inte är en dygd att skriva kod så kompakt som möjligt, utan snarare att skriva så läsbart som möjligt för någon som är van vid fältet. Det innebär att använda idiom och vanliga strukturer för att överraska en läsare (vilket inkluderar dig själv, kanske någon månad senare) så lite som möjligt, vilket även innefattar att inte exempelvis låta en funktion som heter `convertFahr` göra en massa andra saker som man inte skulle förvänta sig. För den som oroar sig för filstorlek och liknande så använder man i stället externa program som exempelvis Closure Compiler som fixar detta automatiskt.