JAVASCRIPT Funktioner
Inledning
När programmen blir större och mer komplicerade är det bra att kunna dela upp programmet i olika delar
som gör specifika saker, vilket kan göra programmet mer lättläst. Ett sätt är att använda funktioner, som är
ett mycket viktig verktyg. En funktion kan ses som ett litet "program i programmet". Det är en
programslinga som man anropar från huvudprogrammet eller en annan funktion och eventuellt skickar med några invärden som
funktionen ska jobba med. Funktionen utför då en uppgift och eventuellt returnerar ett svarsvärde. Funktioner kan byggas på många olika sätt och därför ska vi bekanta oss med några fler möjligheter än de enkla funktioner vi använt hittills i kursen.
En JavaScript funktion definieras genom nyckeordet function, följt av ett funktionsnamn, följt av parenteser ( ).
Funktionsnamn kan innehålla bokstäver, siffror, understreck och dollartecken (vilket är samma som variabler).
En funktion körs (exekveras) enbart när den har blivit anropad.
Några exempel:
function name1( ) {
// kod som ska exekveras
}
function name2(parameter1, parameter2) {
// kod som ska exekveras
}
function name3( ) {
// kod som ska exekveras
return svar;
}
function name4(parameter1, parameter2, parameter3) {
// kod som ska exekveras
return svar;
}
Exempel på olika funktioner
- utan parametrar och utan retur av ett svar
- med parametrar och med retur av svar
- mix av ovanstående
- med array som parameter
Massor av färdiga funktioner
Vi har redan träffat på färdiga funktioner, framför allt vid array-hantering och textsträng-hantering.
Funktion utan parametrar och utan retur av svar
Vi startar med det vi redan känner igen, funktioner som inte har några parametrar och som inte kommer skicka tillbaks något utan dessa funktioner utför bara något.
Vi kan anropa en funktion via "addEventListener", direkt i script-taggen vid inladdning av sidan eller inuti en annan funktion.
Via "addEventListener" och när vi anropar via en timer så har vi inga parentser efter funktionsnamnet.
I huvudprogrammet och i funktionerna sker annars funktionsanrop med funktionsnamnet och parenteser efter.
<body>
<div id="output"></div>
<button type="button" id="knapp">Klicka</button>
<script>
document.getElementById('knapp').addEventListener('click',baa);
function buu() {
document.getElementById('output').innerHTML = "BUUUUUUUUU";
}
function baa() {
document.getElementById('output').innerHTML = "BÄÄÄÄÄÄÄÄÄ";
redColor();
}
function redColor() {
document.getElementById('output').style.backgroundColor = "#F00";
}
buu();
</script>
</body>
Ytterliggare ett exempel där vi också har använder oss av variabler, en global "x" och en lokal "t" som bara är synlig inuti funktionen.
<body>
<input type="text" size="30" id="mintextruta" placeholder="Skriv ditt namn!" value="">
<br /><br />
<button type="button" id="knapp">Klicka</button>
<script>
document.getElementById('knapp').addEventListener('click',heja);
var x=0;
function heja() {
var t = document.getElementById('mintextruta').value;
t = "Hej " + t;
document.getElementById('mintextruta').value = t;
x = x + 1;
if (x > 5) {
document.getElementById('knapp').innerHTML = "SLUTA KLICKA!";
document.getElementById('mintextruta').value = "";
}
}
</script>
</body>
Funktion med parametrar och med retur av svar
I definitionen av en funktion så syns det om den har parametrar, dessa listas då i parentesen efter funktionsnamnet åtskillda med kommatecken.
En funktions argument är de riktiga värden som mottagits då funktionen blivit anropad. Inuti funktionen så fungerar argumenten som lokala variabler.
OBS! När vi anropar en funktion med parametrar som är som vanliga variabler, det vill säga innhåller ett värde så kopieras värdet över till respektive parameternamn . När vi jobbar med parameternamnen i koden inuti funktionen så påverkas inget utanför funktionen. Detta kallas värdeanrop, dvs vi har kopierat ett värde till funktionen.
Nyckelordet return gör att funktionen avslutas och då skickas ett värde tillbaks dit där anropet kom ifrån. Detta värde bör man ta emot då det troligtvis är något som man vill ha och fortsätta använda i sin kod.
Nedan ytterliggare ett exempel med funktioner som har fler parametrar.
<body>
<form>
Beräkna summan av talen: <br />
<input type="text" size="20" id="tal1" value=""><br />
<input type="text" size="20" id="tal2" value=""><br />
<br />
<input type="text" size="30" id="svar" value="">
<br /><br />
<button type="button" id="knapp">Klicka</button>
</form>
<script>
document.getElementById('knapp').addEventListener('click',berakna);
function summera1 (tal1, tal2){
var s = tal1+tal2;
return s;
}
function summera2 (tal1, tal2){
var s = parseFloat(tal1)+parseFloat(tal2);
return s;
}
function berakna()
{
var t1 = document.getElementById('tal1').value;
var t2 = document.getElementById('tal2').value;
if (t1 == "" && isNaN(tal1)) {
alert('Du måste fylla i ett tal!');
document.getElementById('tal1').focus();
}
else if (t2 == "" && isNaN(tal2)) {
alert('Du måste fylla i ett tal!');
document.getElementById('tal2').focus();
}
else {
var sum1 = summera1(t1, t2);
var sum2 = summera2(t1, t2);
var z = "Summan är " + sum1 + " eller " + sum2 + " ! :-/";
document.getElementById('svar').value = z;
}
}
</script>
</body>
Funktioner med parametrar utan return och utan parametrar men med return
<body>
<button type="button" id="knapp">Klicka</button>
<div id="output"></div>
<div id="output2"></div>
<script>
document.getElementById('knapp').addEventListener('click',fixa);
function skrivHej(antal){
var nr = 0, text = "";
while (nr<antal) {
text += "Hej";
nr++;
}
document.getElementById('output').innerHTML = text;
}
function skrivHejsvejs(){
return "<br />Hej svejs i lingonskogen!";
}
function fixa()
{
var text = "";
skrivHej(4);
for (var i=0;i<6;i++) text += skrivHejsvejs();
document.getElementById('output2').innerHTML = text;
}
</script>
</body>
Funktioner med array som parameter, referensanrop
När vi ska ta emot en array som parameter så kommer det skilja sig mot när vi skickade vanliga enkla värden. Array är en typ av objekt i javascript och när vi skickar ett objekt som parameter så sker det med referensanrop. Det innebär att adressen till var objektet finns i arbetminnet kopieras till parametern i funtionen, inte hela objektet. Om vi ändrar något i objektet så kommer det synas utanför funktionen.
Om vi skickar med en array till en funktion så kopieras adressen till var arrayen ligger i arbetsminnet, inte värdena i arrayen. När vi arbetar i funktionen använder vi den lokala variabeln som är en referens till
arrayen. Motsvarande referens finns utanför funktionen i den variabel som vi skickade med i anropet till funktionen. Det vill säga de pekar mot samma ställe i arbetsminnet. Ändrar vi i arrayen och avslutar funktionen så kommer vi åt arrayen utanför med funktionen med den variabel som vi skickade med i anropet till funktionen.
<body>
<button type="button" id="knapp">Klicka</button>
<div id="output"></div>
<script>
document.getElementById('knapp').addEventListener('click',fixa);
function changeBoxZero(arr){
arr[0] = 0;
}
function fixa()
{
var myArray = [3,4,63,2,1,28];
document.getElementById('output').innerHTML = myArray.join()+"<br />";
changeBoxZero(myArray);
document.getElementById('output').innerHTML += myArray.join();
}
</script>
Ytterliggare ett exempel med array som parameter till en funktion.
<body>
<button type="button" id="knapp">Klicka</button>
<div id="output"></div>
<script>
document.getElementById('knapp').addEventListener('click',fixa);
function summeraArray(arr){
var nr = 0, sum = 0;
while (nr<arr.length) {
sum += arr[nr];
nr++;
}
return sum;
}
function analyseraArray(arr, grans){
var nr = 0, antal = 0;
while (nr<arr.length) {
if ( arr[nr] > grans ) antal++;
nr++;
}
return antal;
}
function sortering(arr){
arr.sort( function(a, b) { return a-b; } );
}
function skickaTillbaksTvåVärden(arr) {
var nyArray = [0,0];
for (var i=0; i<arr.length; i++){
if (arr[i]%2==0){ //Summera jämna tal
nyArray[0]+=arr[i];
} else { // summera udda tal
nyArray[1]+=arr[i];
}
}
return nyArray;
}
function fixa()
{
var myArray = [3,4,63,2,1,28];
var myArray2 = myArray;
//
OBS! Blir en referenskopia. Ingen kopia på hela arrayen.
var svarArray = [];
var text = "Summan av talen: " + summeraArray(myArray);
text += "<br />Antal tal över 10: " + analyseraArray(myArray, 10);
text += "<br />Ursprunglig array: " + myArray.join();
sortering(myArray);
text += "<br />Sorterad array: " + myArray.join();
text += "<br />Kopian myArray2: " + myArray2.join();
svarArray = skickaTillbaksTvåVärden(myArray);
text+="<br />Summan av de jämna talen:" + svarArray[0] + " och udda talen: " + svarArray[1];
document.getElementById('output').innerHTML = text;
}
</script>
</body>
Att utveckla
Parametrar med default-värde
Valfritt antal argument
Funktionsuttryck
Funktions hissning (function hoisting)
Slälvkörande funktioner (Self-Invoking Functions)
Källor
HTML5 & CSS3 FOR THE REAL WORLD, Goldstein, Lazaris, Weyl (Sitepoint 2011)
JAVASCRIPT & JQUERY , Jon Duckett (Wiley 2014)