JavaScript-funksjoner. Ekspressiv JavaScript: Fungerer som verdier

Folk tror at informatikk er en kunst for genier. I virkeligheten er det omvendt – bare mange som lager ting som står oppå hverandre, som om de lager en vegg av små rullesteiner.

Donald Knuth

Du har allerede sett anrop til funksjoner som varsling . Funksjoner er brød og smør i JavaScript-programmering. Ideen om å pakke inn et program og kalle det som en variabel er veldig populær. Det er et verktøy for å strukturere store programmer, redusere repetisjon, navngi subrutiner og isolere subrutiner fra hverandre.

Den mest åpenbare bruken av funksjoner er å lage en ny ordbok. Å finne på ord for vanlig menneskelig prosa er dårlig form. Dette er nødvendig i et programmeringsspråk.

Den gjennomsnittlige voksne russisktalende kan omtrent 10 000 ord. Et sjeldent programmeringsspråk inneholder 10 000 innebygde kommandoer. Og vokabularet til et programmeringsspråk er tydeligere definert, så det er mindre fleksibelt enn et menneskelig. Derfor må vi vanligvis legge til egne ord for å unngå unødvendige repetisjoner.

Funksjonsdefinisjon En funksjonsdefinisjon er en normal variabeldefinisjon, der verdien som variabelen mottar er en funksjon. For eksempel definerer følgende kode et variabelt kvadrat, som refererer til en funksjon som beregner kvadratet til et gitt tall:

Var kvadrat = funksjon(x) ( return x * x; ); console.log(kvadrat(12)); // → 144

En funksjon lages av et uttrykk som starter med funksjonsnøkkelordet. Funksjoner har et sett med parametere (i dette tilfellet kun x), og en kropp som inneholder instruksjonene som må utføres når funksjonen kalles. Brødteksten til en funksjon er alltid omsluttet av krøllete klammeparenteser, selv om den består av en enkelt setning.

En funksjon kan ha flere parametere eller ingen i det hele tatt. I følgende eksempel har makeNoise ikke en liste over parametere, men power har to:

Var makeNoise = function() ( console.log("Shit!"); ); lage støy(); // → Khrya! var potens = funksjon(base, eksponent) ( var resultat = 1; for (varantall = 0; antall< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

Noen funksjoner returnerer en verdi, som kraft og kvadrat, andre gjør det ikke, som makeNoise, som bare gir en bieffekt. Return-setningen spesifiserer verdien som returneres av funksjonen. Når programbehandlingen når denne instruksjonen, går den umiddelbart ut av funksjonen og returnerer denne verdien til stedet i koden som funksjonen ble kalt fra. returnere uten et uttrykk returnerer udefinert.

Parametre og omfang Funksjonsparametere er de samme variablene, men deres startverdier settes når funksjonen kalles, og ikke i koden.

En viktig egenskap ved funksjoner er at variabler opprettet i en funksjon (inkludert parametere) er lokale for den funksjonen. Dette betyr at i potenseksemplet vil resultatvariabelen bli opprettet hver gang funksjonen kalles, og disse individuelle inkarnasjonene av den vil ikke ha noe med hverandre å gjøre.

Denne variabellokaliteten gjelder kun for parametere og variabler opprettet i funksjoner. Variabler definert utenfor en hvilken som helst funksjon kalles globale fordi de er synlige gjennom hele programmet. Du kan også få tilgang til slike variabler inne i en funksjon, med mindre du erklærer en lokal variabel med samme navn.

Følgende kode illustrerer dette. Den definerer og kaller opp to funksjoner som tildeler en verdi til variabelen x. Den første erklærer den som lokal, og endrer dermed bare den lokale variabelen. Den andre erklærer ikke, så å jobbe med x inne i funksjonen refererer til den globale variabelen x definert i begynnelsen av eksemplet.

Var x = "utenfor"; var f1 = funksjon() ( var x = "inne f1"; ); f1(); console.log(x); // → utenfor var f2 = funksjon() ( x = "inne f2"; ); f2(); console.log(x); // → inne i f2

Denne virkemåten bidrar til å forhindre utilsiktede interaksjoner mellom funksjoner. Hvis alle variabler ble brukt hvor som helst i et program, ville det være svært vanskelig å sikre at en variabel ikke ble brukt til forskjellige formål. Og hvis du skulle gjenbruke en variabel, ville du støte på merkelige effekter når tredjepartskode ødelegger verdiene til variabelen din. Ved å behandle funksjonslokale variabler slik at de kun eksisterer innenfor funksjonen, gjør språket det mulig å jobbe med funksjoner som om de var separate små universer, slik at du ikke kan bekymre deg for hele koden.

Nested scoping JavaScript skiller mer enn bare mellom globale og lokale variabler. Funksjoner kan defineres innenfor funksjoner, noe som resulterer i flere lokalitetsnivåer.

For eksempel inneholder følgende ganske meningsløse funksjon to til:

Var landskap = funksjon() ( var resultat = ""; var flat = funksjon(størrelse) ( for (varantall = 0; antall< size; count++) result += "_"; }; var mountain = function(size) { result += "/"; for (var count = 0; count < size; count++) result += """; result += "\\"; }; flat(3); mountain(4); flat(6); mountain(1); flat(1); return result; }; console.log(landscape()); // → ___/""""\______/"\_

Flat- og fjellfunksjonene ser resultatvariabelen fordi de er inne i funksjonen som definerer den. Men de kan ikke se hverandres tellevariabler fordi variablene til en funksjon er utenfor rekkevidden til den andre. Og miljøet utenfor landskapsfunksjonen ser ingen av variablene definert inne i denne funksjonen.

Kort sagt, innenfor hvert lokalt scope kan du se alle scopes som inneholder det. Settet med variabler som er tilgjengelige i en funksjon bestemmes av plasseringen der funksjonen er deklarert i programmet. Alle variabler fra blokkene rundt funksjonsdefinisjonen er synlige - inkludert de som er definert på øvre nivå i hovedprogrammet. Denne tilnærmingen til omfang kalles leksikalsk.

Folk som har studert andre programmeringsspråk kan tro at enhver blokk innelukket i krøllete seler skaper sitt eget lokale miljø. Men i JavaScript er det bare funksjoner som skaper omfang. Du kan bruke frittstående blokker:

Var noe = 1; ( var something = 2; // Gjør noe med variabelen noe... ) // Gikk ut av blokken...

Men noe inne i blokken er den samme variabelen som utenfor. Selv om slike blokker er tillatt, er det bare fornuftig å bruke dem for if-setninger og løkker.

Hvis dette virker rart for deg, er du ikke den eneste som synes det. JavaScript 1.7 introduserte søkeordet let, som fungerer som var, men lager variabler som er lokale for en gitt blokk, ikke bare funksjonen.

Funksjoner som verdier Funksjonsnavn brukes vanligvis som navn på et program. En slik variabel settes én gang og endres ikke. Så det er lett å forveksle en funksjon og dens navn.

Men dette er to forskjellige ting. Et funksjonskall kan brukes som en enkel variabel - for eksempel brukt i ethvert uttrykk. Det er mulig å lagre et funksjonskall i en ny variabel, sende det som en parameter til en annen funksjon, og så videre. Variabelen som lagrer funksjonskallet forblir også en vanlig variabel og verdien kan endres:

Var launchMissiles = funksjon(verdi) (missileSystem.launch("eller!"); ); if (safeMode) launchMissiles = funksjon(verdi) (/* avbryt */);

I kapittel 5 vil vi diskutere de fantastiske tingene du kan gjøre ved å sende funksjonskall til andre funksjoner.

Erklære funksjoner Det finnes en kortere versjon av uttrykket "var square = function...". Funksjonsnøkkelordet kan brukes i begynnelsen av en setning:

Funksjon kvadrat(x) ( return x * x; )

Dette er en funksjonserklæring. Utsagnet definerer kvadratvariabelen og tildeler den gitte funksjonen. Så langt så bra. Det er bare én fallgruve i en slik definisjon.

Console.log("Fremtiden sier:", future()); function future() ( return "Vi har FORTSATT ingen flygende biler."; )

Denne koden fungerer selv om funksjonen er deklarert under koden som bruker den. Dette er fordi funksjonserklæringer ikke er en del av normal programkjøring ovenfra og ned. De blir "flyttet" til toppen av omfanget og kan kalles opp av hvilken som helst kode i det omfanget. Noen ganger er dette praktisk fordi du kan skrive kode i den rekkefølgen som gir mest mening uten å måtte bekymre deg for å måtte definere alle funksjonene ovenfor hvor de brukes.

Hva skjer hvis vi plasserer en funksjonserklæring inne i en betinget blokk eller sløyfe? Du trenger ikke å gjøre det. Historisk sett har forskjellige JavaScript-plattformer håndtert slike saker forskjellig, og gjeldende språkstandard forbyr dette. Hvis du vil at programmene dine skal kjøre sekvensielt, bruk funksjonserklæringer kun innenfor andre funksjoner eller hovedprogrammet.

Funksjonseksempel() ( funksjon a() () // Normal if (noe) ( funksjon b() () // Ay-yay-yay! ) )

Call Stack Det er nyttig å se nærmere på hvordan utførelsesordre fungerer med funksjoner. Her enkelt program med flere funksjonskall:

Funksjon greet(who) ( console.log("Hei, " + hvem); ) greet("Semyon"); console.log("Pokeda");

Det behandles omtrent slik: å ringe greet får passet til å hoppe til begynnelsen av funksjonen. Den kaller den innebygde console.log-funksjonen, som fanger opp kontroll, gjør sitt og returnerer kontroll. Så kommer han til slutten av hilsen, og går tilbake til stedet han ble kalt fra. Den neste linjen kaller console.log igjen.

Dette kan vises skjematisk slik:

Top greet console.log greet top console.log top

Fordi funksjonen må gå tilbake til stedet den ble kalt fra, må datamaskinen huske konteksten funksjonen ble kalt fra. I ett tilfelle skal console.log komme tilbake for å hilse. I en annen går hun tilbake til slutten av programmet.

Stedet der datamaskinen husker konteksten kalles stabelen. Hver gang en funksjon kalles, skyves gjeldende kontekst til toppen av stabelen. Når funksjonen kommer tilbake, henter den toppkonteksten fra stabelen og bruker den til å fortsette å kjøre.

Lagring av en stabel krever minneplass. Når stabelen blir for stor, vil datamaskinen slutte å kjøre og si noe som "stabeloverflyt" eller "for mye rekursjon." Følgende kode demonstrerer dette - den stiller datamaskinen et veldig komplekst spørsmål, som fører til endeløse hopp mellom to funksjoner. Mer presist ville det vært uendelige hopp hvis datamaskinen hadde en uendelig stack. I virkeligheten renner stabelen over.

Funksjon kylling() ( return egg(); ) funksjon egg() ( return kylling(); ) console.log(kylling() + " kom først."); // → ??

Valgfrie argumenter Følgende kode er fullstendig lovlig og kjører uten problemer:

Alert("Hei", "God kveld", "Hei alle sammen!");

Offisielt tar funksjonen ett argument. Men når hun blir utfordret på denne måten, klager hun ikke. Hun ignorerer resten av argumentene og viser «Hei».

JavaScript er veldig spesielt med hensyn til antall argumenter som sendes til en funksjon. Hvis du overfører for mye, vil de ekstra ignoreres. For få og de som mangler vil bli tildelt verdien undefined.

Ulempen med denne tilnærmingen er at det er mulig – og til og med sannsynlig – å sende feil antall argumenter til en funksjon uten at noen klager på det.

Fordelen er at du kan lage funksjoner som tar valgfrie argumenter. For eksempel, i neste versjon av potensfunksjonen, kan den kalles med enten to eller ett argument - i sistnevnte tilfelle vil eksponenten være lik to, og funksjonen fungerer som en firkant.

Funksjonspott(base, eksponent) (hvis (eksponent == udefinert) eksponent = 2; var resultat = 1; for (varantall = 0; antall< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

I neste kapittel skal vi se hvordan du kan finne ut det eksakte antallet argumenter som sendes til en funksjon i brødteksten. Dette er nyttig fordi... lar deg lage en funksjon som tar et hvilket som helst antall argumenter. For eksempel bruker console.log denne egenskapen og skriver ut alle argumentene som sendes til den:

Console.log("R", 2, "D", 2); // → R 2 D 2

Lukkinger Evnen til å bruke funksjonskall som variabler, kombinert med det faktum at lokale variabler opprettes på nytt hver gang en funksjon kalles opp, leder oss til et interessant spørsmål. Hva skjer med lokale variabler når en funksjon slutter å virke?

Følgende eksempel illustrerer dette problemet. Den erklærer wrapValue-funksjonen, som lager en lokal variabel. Den returnerer deretter en funksjon som leser denne lokale variabelen og returnerer verdien.

Funksjon wrapVariable(n) ( var localVariable = n; return function() (retur localVariable; ); ) var wrap1 = wrapValue(1); var wrap2 = wrapValue(2); console.log(wrap1()); // → 1 console.log(wrap2()); // → 2

Dette er gyldig og fungerer som det skal - tilgangen til variabelen består. Dessuten kan flere forekomster av samme variabel eksistere samtidig, noe som ytterligere bekrefter det faktum at lokale variabler gjenskapes med hvert funksjonskall.

Denne evnen til å arbeide med en referanse til en forekomst av en lokal variabel kalles en closure. En funksjon som lukker lokale variabler kalles en lukking. Ikke bare frigjør det deg fra å bekymre deg for varierende levetid, men det lar deg også bruke funksjoner kreativt.

Med en liten modifikasjon gjør vi eksemplet vårt til en funksjon som multipliserer tall med et gitt tall.

Funksjonsmultiplikator(faktor) ( returner funksjon(tall) ( returner tall * faktor; ); ) var to ganger = multiplikator(2); console.log(to ganger(5)); // → 10

En separat variabel som localVariable fra wrapValue-eksemplet er ikke lenger nødvendig. Siden parameteren i seg selv er en lokal variabel.

Det vil kreve øvelse å begynne å tenke på denne måten. En god mental modell er å forestille seg at en funksjon fryser koden i kroppen og pakker den inn i en pakke. Når du ser returfunksjon(...) (...), tenk på det som et kontrollpanel for en kodebit som er frosset for senere bruk.

I vårt eksempel returnerer multiplikator en frossen kodebit, som vi lagrer i to ganger-variabelen. Den siste linjen kaller funksjonen som ligger i variabelen, som gjør at den lagrede koden aktiveres (returnummer * faktor;). Den har fortsatt tilgang til faktorvariabelen som ble definert ved kalle multiplikator, og den har også tilgang til argumentet som sendes under avriming (5) som en numerisk parameter.

Rekursjon En funksjon kan godt kalle seg selv så lenge den passer på å ikke flyte over stabelen. Denne funksjonen kalles rekursiv. Her er et eksempel på en alternativ implementering av eksponentiering:

Funksjon power(base, eksponent) ( if (eksponent == 0) return 1; else return base * power(base, exponent - 1); ) console.log(power(2, 3)); // → 8

Det er omtrent slik matematikere definerer eksponentiering, og kanskje beskriver dette konseptet mer elegant enn en syklus. Funksjonen kaller seg selv mange ganger med forskjellige argumenter for å oppnå multiplikasjon.

Denne implementeringen har imidlertid et problem - i et vanlig JavaScript-miljø er den 10 ganger tregere enn versjonen med en loop. Å gå gjennom en løkke er billigere enn å ringe en funksjon.

Hastighet versus eleganse-dilemmaet er ganske interessant. Det er et visst gap mellom bekvemmelighet for mennesker og bekvemmelighet for maskiner. Ethvert program kan økes ved å gjøre det større og mer intrikat. Programmereren må finne riktig balanse.

Når det gjelder den første eksponentieringen, er den uelegante løkken ganske enkel og grei. Det gir ikke mening å erstatte det med rekursjon. Ofte omhandler imidlertid programmer så komplekse konsepter at man ønsker å redusere effektiviteten ved å øke lesbarheten.

Grunnregelen, som har blitt gjentatt mer enn én gang, og som jeg er helt enig i, er å ikke bekymre deg for ytelsen før du er helt sikker på at programmet bremser opp. Finn i så fall delene som varer lengst og bytt eleganse for effektivitet der.

Vi skal selvfølgelig ikke ignorere ytelsen helt med en gang. I mange tilfeller, som med eksponentiering, får vi ikke mye enkelhet fra elegante løsninger. Noen ganger kan en erfaren programmerer se med en gang at den enkle tilnærmingen aldri vil være rask nok.

Jeg påpeker dette fordi for mange nybegynnere programmerere er besatt av effektivitet selv i små ting. Resultatet er større, mer komplekst og ofte ikke uten feil. Slike programmer tar lengre tid å skrive, men de fungerer ofte ikke mye raskere.

Men rekursjon er ikke alltid bare et mindre effektivt alternativ til loops. Noen problemer er lettere å løse med rekursjon. Oftest er dette en kryssing av flere grener av et tre, som hver kan forgrene seg.

Her er en gåte: du kan få et uendelig antall tall ved å starte med tallet 1, og deretter enten legge til 5 eller gange med 3. Hvordan skriver vi en funksjon som, gitt et tall, prøver å finne sekvensen av addisjoner og multiplikasjoner som fører til et gitt tall? For eksempel kan tallet 13 fås ved først å multiplisere 1 med 3 og deretter legge til 5 to ganger. Og tallet 15 kan ikke oppnås på denne måten i det hele tatt.

Rekursiv løsning:

Funksjon findSolution(target) ( function find(start, history) ( if (start == target) return history; else if (start > target) return null; else return find(start + 5, "(" + history + " + 5)") || finn(start * 3, "(" + historikk + " * 3)"); ) returner finn(1, "1"); ) console.log(finnSolution(24)); // → (((1 * 3) + 5) * 3)

Dette eksempelet finner ikke nødvendigvis den korteste løsningen – det tilfredsstilles av evt. Jeg forventer ikke at du umiddelbart forstår hvordan programmet fungerer. Men la oss forstå denne flotte øvelsen i rekursiv tenkning.

Den indre funksjonen finner gjør rekursjon. Det krever to argumenter - det gjeldende tallet og en streng som inneholder en oversikt over hvordan vi kom frem til dette tallet. Og den returnerer enten en streng som viser trinnsekvensen vår, eller null.

For å gjøre dette utfører funksjonen en av tre handlinger. Hvis det gitte tallet er lik målet, er den nåværende historien nettopp måten å oppnå det på, så den kommer tilbake. Hvis det gitte tallet er større enn målet, er det ingen vits i å fortsette å multiplisere og addere, for det vil bare øke. Og hvis vi ikke har nådd målet ennå, prøver funksjonen begge mulige veier som starter med det gitte tallet. Hun tilkaller seg selv to ganger, en gang med hver metode. Hvis det første anropet ikke returnerer null, returneres det. I et annet tilfelle returneres den andre.

For bedre å forstå hvordan funksjonen oppnår ønsket effekt, la oss se på samtalene den gjør for å finne en løsning på tallet 13.

Finn(1, "1") finn(6, "(1 + 5)") finn(11, "((1 + 5) + 5)") finn(16, "(((1 + 5) + 5) ) + 5)") for stort funn(33, "(((1 + 5) + 5) * 3)") for stort funn(18, "((1 + 5) * 3)") for stort funn( 3, "(1 * 3)") finn(8, "((1 * 3) + 5)") finn(13, "(((1 * 3) + 5) + 5)") funnet!

Innrykk viser dybden på anropsstakken. Den første gangen kaller finnfunksjonen seg selv to ganger for å sjekke løsninger som starter med (1 + 5) og (1 * 3). Den første samtalen ser etter en løsning som starter med (1 + 5) og bruker rekursjon for å sjekke alle løsninger som produserer et tall mindre enn eller lik det nødvendige antallet. Finner den ikke og returnerer null. Deretter operatøren || og går videre til et funksjonskall som undersøker alternativet (1 * 3). Vi er heldige her, for i det tredje rekursive kallet får vi 13. Dette kallet returnerer en streng, og hver av || underveis passerer den denne linjen høyere, noe som resulterer i å returnere en løsning.

Voksende funksjoner Det er to mer eller mindre naturlige måter å introdusere funksjoner i et program.

Den første er at du skriver lignende kode flere ganger. Dette bør unngås – mer kode betyr mer rom for feil og mer lesestoff for de som prøver å forstå programmet. Så vi tar en tilbakevendende funksjonalitet, gir den et godt navn og setter den inn i en funksjon.

Den andre måten er at du oppdager et behov for noe ny funksjonalitet som er verdig å plasseres i en egen funksjon. Du starter med navnet på funksjonen, og skriver deretter kroppen. Du kan til og med begynne med å skrive koden som bruker funksjonen før selve funksjonen er definert.

Hvor vanskelig det er for deg å navngi en funksjon viser hvor godt du forstår funksjonaliteten. La oss ta et eksempel. Vi må skrive et program som skriver ut to tall, antall kyr og kyllinger på gården, etterfulgt av ordene "kyr" og "kyllinger." Du må legge til nuller til tallene foran slik at hver enkelt opptar nøyaktig tre posisjoner.

007 Kyr 011 Kyllinger

Selvfølgelig trenger vi en funksjon med to argumenter. La oss begynne å kode.
// print FarmInventory-funksjon printFarmInventory(kyr, kyllinger) ( var cowString = String(cows); while (cowString.length< 3) cowString = "0" + cowString; console.log(cowString + " Коров"); var chickenString = String(chickens); while (chickenString.length < 3) chickenString = "0" + chickenString; console.log(chickenString + " Куриц"); } printFarmInventory(7, 11);

Hvis vi legger til .length til en streng, får vi lengden. Det viser seg at while-løkkene legger innledende nuller til tallene til de får en linje med 3 tegn.

Klar! Men akkurat i det vi skulle sende koden til bonden (sammen med en heftig sjekk, selvfølgelig), ringer han og forteller at han har griser på gården sin, og kan vi legge til en visning av antall griser til program?

Selvfølgelig er det mulig. Men når vi begynner å kopiere og lime inn koden fra disse fire linjene, skjønner vi at vi må stoppe opp og tenke. Det må finnes en bedre måte. Vi prøver å forbedre programmet:

// output MED Legge til nuller OG etiketter-funksjon printZeroPaddedWithLabel(nummer, etikett) ( var numberString = String(nummer); while (numberString.length< 3) numberString = "0" + numberString; console.log(numberString + " " + label); } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { printZeroPaddedWithLabel(cows, "Коров"); printZeroPaddedWithLabel(chickens, "Куриц"); printZeroPaddedWithLabel(pigs, "Свиней"); } printFarmInventory(7, 11, 3);

Virker! Men navnet printZeroPaddedWithLabel er litt rart. Den kombinerer tre ting – utdata, å legge til nuller og en etikett – i én funksjon. I stedet for å sette inn et helt repeterende fragment i en funksjon, la oss fremheve ett konsept:

// legg til nullfunksjon nullPad(nummer, bredde) ( var string = String(tall); while (string.length< width) string = "0" + string; return string; } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { console.log(zeroPad(cows, 3) + " Коров"); console.log(zeroPad(chickens, 3) + " Куриц"); console.log(zeroPad(pigs, 3) + " Свиней"); } printFarmInventory(7, 16, 3);

En funksjon med et fint, tydelig navn zeroPad gjør koden lettere å forstå. Og den kan brukes i mange situasjoner, ikke bare i vårt tilfelle. For eksempel for å vise formaterte tabeller med tall.

Hvor smarte og allsidige skal funksjonene være? Vi kan skrive en enkel funksjon som fyller ut et tall med nuller opp til tre posisjoner, eller en sofistikert generell funksjon for formatering av tall som støtter brøker, negative tall, punktjustering, utfylling osv.

En god tommelfingerregel er å bare legge til funksjonalitet som du vet vil være nyttig. Noen ganger er det fristende å lage generelle rammer for ethvert lite behov. Motstå ham. Du vil aldri fullføre jobben, du vil bare ende opp med å skrive en haug med kode som ingen vil bruke.

Funksjoner og bivirkninger Funksjoner kan grovt deles inn i de som kalles for sine bivirkninger og de som kalles for å oppnå en viss verdi. Det er selvfølgelig også mulig å kombinere disse egenskapene i én funksjon.

Den første hjelpefunksjonen i gårdseksemplet, printZeroPaddedWithLabel, kalles fordi den har en bivirkning: den skriver ut en streng. Den andre, zeroPad, på grunn av returverdien. Og det er ikke tilfeldig at den andre funksjonen kommer til nytte oftere enn den første. Funksjoner som returnerer verdier er lettere å kombinere med hverandre enn funksjoner som gir bivirkninger.

En ren funksjon er en spesiell type verdi-returnerende funksjon som ikke bare har ingen bivirkninger, men som heller ikke er avhengig av bivirkningene av resten av koden - for eksempel fungerer den ikke med globale variabler som kan være tilfeldig endret et annet sted. En ren funksjon, når den kalles med de samme argumentene, returnerer det samme resultatet (og gjør ingenting annet) - noe som er ganske fint. Hun er lett å jobbe med. Et kall til en slik funksjon kan mentalt erstattes av resultatet av arbeidet, uten å endre betydningen av koden. Når du vil teste en slik funksjon, kan du ganske enkelt kalle den, og være sikker på at hvis den fungerer i en gitt kontekst, vil den fungere i enhver sammenheng. Mindre rene funksjoner kan gi ulike resultater avhengig av mange faktorer, og ha bivirkninger som er vanskelige å teste og redegjøre for.

Du bør imidlertid ikke være flau for å skrive funksjoner som ikke er helt rene, eller å begynne en hellig koderensing av slike funksjoner. Bivirkninger er ofte gunstige. Det er ingen måte å skrive en ren versjon av console.log-funksjonen på, og denne funksjonen er ganske nyttig. Noen operasjoner er lettere å uttrykke ved hjelp av bivirkninger.

Sammendrag Dette kapittelet viste deg hvordan du skriver dine egne funksjoner. Når funksjonsnøkkelordet brukes som et uttrykk, returnerer en peker til funksjonskallet. Når den brukes som en instruksjon, kan du deklarere en variabel ved å tilordne et funksjonskall til den.

Nøkkelen til å forstå funksjoner er lokalt omfang. Parametre og variabler deklarert inne i en funksjon er lokale for den, gjenskapes hver gang den kalles opp, og er ikke synlige fra utsiden. Funksjoner som er deklarert i en annen funksjon har tilgang til dens omfang.

Det er veldig nyttig å dele de forskjellige oppgavene som utføres av et program i funksjoner. Du trenger ikke å gjenta deg selv; funksjoner gjør koden mer lesbar ved å dele den inn i meningsfulle deler, akkurat som kapitler og deler av en bok hjelper til med å organisere vanlig tekst.

OppgaverMinimum I forrige kapittel nevnte vi Math.min-funksjonen, som returnerer det minste av argumentene. Nå kan vi skrive en slik funksjon selv. Skrive min funksjon, som tar to argumenter og returnerer minimum av dem.

Console.log(min(0, 10)); // → 0 console.log(min(0, -10)); // → -10

Rekursjon Vi har sett at % (modulo) operatoren kan brukes til å bestemme om et tall (%2) er partall. Her er en annen måte å definere det på:

Null er jevnt.
Enheten er merkelig.
Ethvert tall N har samme paritet som N-2.

Skriv en rekursiv funksjon er Selv i henhold til disse reglene. Den må godta et tall og returnere en boolsk verdi.

Test den ved 50 og 75. Prøv å gi den -1. Hvorfor oppfører hun seg på denne måten? Er det mulig å fikse det på en eller annen måte?

Test den på 50 og 75. Se hvordan den oppfører seg på -1. Hvorfor? Kan du tenke på en måte å fikse dette på?

Console.log(isEven(50)); // → true console.log(isEven(75)); // → false console.log(isEven(-1)); // → ??

Å telle bønnene.

Tegnnummeret N til en streng kan fås ved å legge til .charAt(N) ("string".charAt(5)) til den - på samme måte som å få lengden på en streng ved å bruke .length. Returverdien vil være en streng som består av ett tegn (for eksempel "k"). Det første tegnet på linjen har posisjon 0, som betyr at siste tegn posisjon vil være string.length – 1. Med andre ord vil en streng med to tegn ha lengde 2, og tegnposisjonene vil være 0 og 1.

Skriv en funksjon countBs som tar en streng som et argument og returnerer antall "B"-tegn i strengen.

Skriv deretter en funksjon kalt countChar, som fungerer omtrent som countBs, men som tar en andre parameter - tegnet vi skal se etter i strengen (i stedet for å bare telle antall "B"-tegn). For å gjøre dette, omarbeid countBs-funksjonen.

Hoppsetninger og unntakshåndtering

En annen kategori av JavaScript-operatorer er hoppoperatorer. Som navnet antyder, får disse operatørene JavaScript-tolken til å hoppe til et annet sted i programkoden. Break-setningen får tolken til å hoppe til slutten av en loop eller annen setning. Fortsett-setningen får tolken til å hoppe over resten av løkken, hoppe tilbake til begynnelsen av løkken og begynne å utføre en ny iterasjon. JavaScript har muligheten til å merke setninger med navn, så break and continue-setninger kan eksplisitt indikere hvilken loop eller annen setning de tilhører.

Return-setningen får tolken til å hoppe fra den kalte funksjonen tilbake til punktet den ble kalt og returnere verdien av anropet. throw-setningen gir et unntak og er designet for å fungere sammen med try/catch/finally-setninger, som definerer en kodeblokk for å håndtere unntaket. Dette er en ganske kompleks type hoppoperator: når et unntak oppstår, hopper tolken til nærmeste omsluttende unntaksbehandler, som kan være i samme funksjon eller høyere i returstabelen til den kalte funksjonen.

Alle disse hoppoperatorene er beskrevet mer detaljert i de følgende underavsnittene.

Instruksjonsmerker

Enhver instruksjon kan merkes med en identifikator og et kolon:

ID: instruksjon

Ved å merke en instruksjon gir du den et navn, som deretter kan brukes som referanse hvor som helst i programmet. Du kan merke hvilken som helst instruksjon, men det er bare fornuftig å merke instruksjoner som har en kropp, for eksempel looper og betingede utsagn.

Ved å tildele et navn til en løkke, kan den deretter brukes i pause- og fortsettsetninger, inne i en løkke for å gå ut av den, eller for å hoppe til begynnelsen av løkken til neste iterasjon. Break- og fortsett-setningene er de eneste JavaScript-setningene som kan inneholde etiketter – vi vil dekke dem mer detaljert senere. Følgende er et eksempel på en while-setning med en etikett og en fortsett-setning som bruker den etiketten:

Mainloop: while (token != null) ( // Programkode utelatt... fortsett mainloop; // Gå til neste iterasjon av den navngitte loopen)

Identifikatoren som brukes som en setningsetikett kan være en hvilken som helst gyldig JavaScript-identifikator bortsett fra et reservert ord. Etikettnavn er atskilt fra variabel- og funksjonsnavn, så identifikatorer som samsvarer med variabel- eller funksjonsnavn kan brukes som etiketter.

Instruksjonsetiketter er bare definert innenfor instruksjonene de gjelder for (og selvfølgelig innenfor instruksjonene som er nestet i dem). Nestede setninger kan ikke merkes med samme identifikatorer som de inneholder setninger, men to uavhengige setninger kan merkes med samme etikett. Flaggede instruksjoner kan flagges på nytt. Det vil si at enhver instruksjon kan ha mange etiketter.

bryte uttalelse

Break-setningen fører til at den innerste løkken eller switch-setningen avsluttes umiddelbart. Vi har tidligere sett eksempler på bruk av break-setningen inne i en switch-setning. I sløyfer brukes det vanligvis til umiddelbart å gå ut av sløyfen når sløyfen må avsluttes av en eller annen grunn.

Når syklusen har veldig vanskelig tilstand fullføring, er det ofte lettere å implementere disse betingelsene ved å bruke en break-setning enn å prøve å uttrykke dem i et enkelt sløyfe-betinget uttrykk. Følgende eksempel prøver å finne et matriseelement med en bestemt verdi. Sløyfen slutter normalt når den når slutten av matrisen, eller med en break-setning når verdien som søkes er funnet:

Var arr = ["a","b","c","d","d"], resultat; for (var i = 0; i

I JavaScript kan du spesifisere navnet på etiketten etter break-nøkkelordet (identifikator uten kolon):

bryte label_name;

Når en break-setning brukes med en etikett, hopper den til slutten av den navngitte setningen eller avslutter utførelsen. Hvis det ikke er noen setning med den angitte etiketten, vil forsøk på å bruke denne formen for break-setningen generere en syntaksfeil. Den navngitte setningen trenger ikke å være en sløyfe- eller switch-setning. En bruddsetning med en etikett kan bryte ut av en hvilken som helst setning som inneholder. En innpakningsinstruksjon kan til og med være en enkel blokk med instruksjoner omsluttet av krøllete bukseseler med det eneste formålet å merke den.

Du kan ikke sette inn et linjeskifttegn mellom nøkkelordet break og etikettnavnet. Dette er fordi JavaScript-tolkeren automatisk setter inn manglende semikolon: hvis du deler en kodelinje mellom break-nøkkelordet og følgende etikett, vil tolken anta at du mente den enkle formen av setningen uten etiketten, og vil legge til et semikolon.

En merket break-setning er bare nødvendig når du vil avbryte utførelsen av en setning som ikke er den nærmeste omsluttende sløyfen eller switch-setningen.

Fortsett operatør

Fortsett-setningen ligner på pauseerklæringen. Men i stedet for å gå ut av loopen, starter continu-setningen en ny iterasjon av loopen. Syntaksen til continu-setningen er like enkel som syntaksen til break-setningen. Fortsett-setningen kan også brukes med en etikett.

Fortsett-setningen, både i skjemaet uten etikett og med etikett, kan bare brukes i hoveddelen av en loop. Å bruke det andre steder resulterer i en syntaksfeil. Når continu-setningen utføres, avbrytes den nåværende iterasjonen av løkken og den neste begynner. Til forskjellige typer sykluser betyr dette forskjellige ting:

    I en while-løkke kontrolleres uttrykket som er spesifisert i begynnelsen av løkken igjen, og hvis det er sant, utføres løkkens kropp fra begynnelsen.

    En do/while-løkke hopper til slutten av løkken, hvor tilstanden kontrolleres på nytt før løkken utføres igjen.

    For-løkken evaluerer inkrementuttrykket og evaluerer testuttrykket på nytt for å bestemme om neste iterasjon skal utføres.

    I en for/in-løkke starter loopen på nytt ved å tilordne den angitte variabelen til navnet på neste egenskap.

Legg merke til forskjellene i oppførselen til continu-setningen i while og for loops. En while-løkke går direkte tilbake til tilstanden, mens en for-løkke først evaluerer inkrementuttrykket og deretter går tilbake til betingelsen. Følgende eksempel viser bruken av en continue-setning uten en etikett for å avslutte gjeldende loop-iterasjon for partall:

Var sum = 0; // Regn ut summen av oddetall fra 0 - 10 for (var i = 0; i

Continue-setningen, som break, kan brukes i nestede løkker i en form som inkluderer en etikett, og da vil løkken som startes på nytt ikke nødvendigvis være en løkke som direkte inneholder continu-setningen. I tillegg, som med pause, er linjeskift ikke tillatt mellom fortsett-nøkkelordet og etikettnavnet.

returoppgave

Et funksjonskall er et uttrykk og har, som alle uttrykk, en verdi. Return-setningen i funksjoner brukes til å bestemme verdien som returneres av funksjonen. Return-setningen kan bare vises i brødteksten til en funksjon. Dens tilstedeværelse på et hvilket som helst annet sted er en syntaksfeil. Når en return-setning utføres, returnerer funksjonen verdien av uttrykket til det kallende programmet. For eksempel:

Hvis en funksjon ikke har en return-setning, når den kalles, vil tolken utføre setningene i funksjonskroppen én etter én til den når slutten av funksjonen, og deretter returnere kontrollen til programmet som kalte den. I dette tilfellet vil kalleuttrykket returnere udefinert. Returoppgaven er ofte siste instruksjon i funksjonen, men dette er helt valgfritt: funksjonen vil returnere kontroll til det anropende programmet så snart en retursetning er nådd, selv om den blir fulgt av andre setninger i funksjonskroppen.

Return-setningen kan også brukes uten et uttrykk, i så fall avbryter den ganske enkelt funksjonen og returnerer udefinert til det kallende programmet. For eksempel:

Funksjon myFun(arr) ( // Hvis matrisen inneholder negative tall, avbryt funksjonen for (var i = 0; i

kaste uttalelse

Et unntak er et signal som indikerer at en slags eksepsjonell situasjon eller feil har oppstått. Kaster et unntak er en måte å signalisere en slik feil eller unntak. Å fange et unntak betyr å behandle det, dvs. iverksette nødvendige eller passende tiltak for å komme seg fra unntaket.

I JavaScript blir unntak kastet når en kjøretidsfeil oppstår og når programmet eksplisitt hever den ved hjelp av en throw-setning. Unntak fanges opp ved hjelp av try/catch/finally-setninger, som beskrives senere.

throw-setningen har følgende syntaks:

kaste uttrykk;

Resultatet av uttrykket kan være en verdi av hvilken som helst type. Throw-setningen kan sendes et tall som representerer en feilkode eller en streng som inneholder teksten til feilmeldingen. JavaScript-tolken kaster unntak ved å bruke en forekomst av Error-klassen til en av underklassene, og du kan bruke en lignende tilnærming. Error-objektet har en egenskap Navn, som definerer typen feil og egenskapen beskjed, som inneholder strengen som er sendt til konstruktørfunksjonen. Følgende er et eksempel på en funksjon som reiser et Error-objekt når det kalles opp med et ugyldig argument:

// Tallfaktoriell funksjon funksjon factorial(tall) ( // Hvis input-argumentet ikke er en gyldig verdi, // blir det kastet et unntak! if (nummer 1; i *= tall, tall--); /* tomt sløyfelegeme */ return i ; ) console.log("5! = ", faktoriell(5)); console.log("-3! = ", faktoriell(-3));

Når et unntak oppstår, avbryter JavaScript-tolken umiddelbart normal programkjøring og hopper til nærmeste unntaksbehandler. Unntaksbehandlere bruker try/catch/finally catch-klausulen, som er beskrevet i neste avsnitt.

Hvis kodeblokken der unntaket skjedde ikke har en tilsvarende catch-konstruksjon, undersøker tolken den neste ytre kodeblokken og sjekker om en unntaksbehandler er knyttet til den. Dette fortsetter til en behandler er funnet.

Hvis et unntak blir kastet i en funksjon som ikke inneholder en try/catch/finally-konstruksjon for å håndtere det, forplanter unntaket seg til koden som kalte funksjonen. På denne måten spres unntak gjennom den leksikalske strukturen til JavaScript-metoder opp i anropsstakken. Hvis en unntaksbehandler aldri blir funnet, behandles unntaket som en feil og rapporteres til brukeren.

prøv/fang/konstruer til slutt

Try/catch/finally-konstruksjonen implementerer unntakshåndteringsmekanismen i JavaScript. Try-setningen i denne konstruksjonen definerer ganske enkelt en kodeblokk der unntak håndteres. Try-blokken etterfølges av en catch-setning med en blokk med setninger som kalles hvis et unntak oppstår hvor som helst i try-blokken. Catch-setningen etterfølges av en finally-blokk, som inneholder den endelige koden som garantert kjører uavhengig av hva som skjer i try-blokken.

Både fangstblokken og den endelige blokken er valgfrie, men minst en av dem må være til stede etter prøveblokken. Prøv, fang og til slutt blokkerer start og slutt krøllete regulering. Dette er en nødvendig del av syntaksen og kan ikke utelates, selv om det bare er én instruksjon i mellom.

Følgende utdrag illustrerer syntaksen og formålet med try/catch/finally-konstruksjonen:

Prøv ( // Denne koden kjører vanligvis jevnt fra start til slutt. // Men på et tidspunkt kan den gi et unntak // enten direkte ved å bruke throw-setningen, eller indirekte // ved å kalle en metode som kaster unntaket. ) catch ( ex) ( // Utsagnene i denne blokken utføres hvis og bare hvis et unntak // forekommer i try-blokken. Disse utsagn kan bruke den lokale variabelen ex, som // refererer til et Error-objekt eller en annen verdi spesifisert i kastet setning. // Denne blokken kan enten håndtere unntaket på en eller annen måte, // ignorere det mens du gjør noe annet, eller kaste unntaket på nytt // ved å bruke en throw-setning. ) til slutt ( // Denne blokken inneholder setninger som alltid utføres , uavhengig av , // hva som skjedde i try-blokken De utføres hvis try-blokken er fullført: // 1) som vanlig, etter å ha nådd slutten av blokken // 2) på grunn av en pause, fortsette eller returnere uttalelse / / 3) med unntaket som håndteres av den i catch-blokken over // 4) med et ufanget unntak som fortsetter å forplante seg // til høyere nivåer)

Merk at catch-nøkkelordet er etterfulgt av en identifikator i parentes. Denne identifikatoren ligner på en funksjonsparameter. Når et unntak fanges opp, vil denne parameteren bli tildelt unntaket (for eksempel et Error-objekt). I motsetning til en vanlig variabel, eksisterer identifikatoren knyttet til en catch-setning bare i hoveddelen av catch-blokken.

Følgende er et mer realistisk eksempel på en prøve/fangst-konstruksjon. Den kaller faktorial()-metoden definert i forrige eksempel og klientens JavaScript-prompt() og alert()-metoder for å organisere input og output:

Prøv ( // Spør brukeren om et tall var n = Number(prompt("Skriv inn et positivt tall", "")); // Beregn faktoren til et tall, forutsatt at // at inndata er riktig var f = faktorial (n); // Skriv ut resultatvarsel(n + "! = " + f); ) catch (ex) ( // Hvis dataene er feil, vil kontrollen bli overført hit alert(ex); // Informer brukeren om feilen)

Hvis brukeren angir et negativt tall, vises en advarsel:

Dette er et eksempel på en try/catch-konstruksjon uten en finally-klausul. Selv om det til slutt ikke brukes så ofte som fangst, er det fortsatt nyttig noen ganger. Den endelige blokken er garantert å kjøre hvis i det minste en del av prøveblokken har blitt utført, uavhengig av hvordan koden i prøveblokken fullførte kjøringen. Denne funksjonen brukes vanligvis til å utføre siste operasjoner etter utføring av kode i en forsøksfortsettelse.

I en normal situasjon når kontrollen slutten av prøveblokken og går deretter til den endelige blokken, som utfører de nødvendige siste operasjonene. Hvis kontroll går ut av en try-blokk som et resultat av en retur-, continue- eller break-setning, utføres finally-blokken før kontroll overføres til andre steder.

Hvis et unntak oppstår i en prøveblokk og det er en tilsvarende fangblokk for å håndtere den, går kontrollen først til fangblokken og deretter til den endelige blokken. Hvis det ikke er noen lokal fangblokk, går kontrollen først til den endelige blokken og flytter deretter til nærmeste ytre fangblokk som kan håndtere unntaket.

Hvis den endelige blokken i seg selv overfører kontroll ved å bruke en retur-, fortsett-, break- eller throw-setning eller ved å kalle en metode som kaster et unntak, avbrytes den ventende overføringskommandoen og en ny blir utført. For eksempel, hvis en endelig blokk gir et unntak, vil dette unntaket erstatte ethvert tidligere kastet unntak.

Return-setningen avslutter utførelsen av gjeldende funksjon og returnerer verdien.

Kildekoden for dette interaktive eksemplet er lagret i et depot på GitHub. Hvis du vil bidra til prosjektet med interaktive eksempler, vennligst klon https://github.com/mdn/interactive-examples

Syntaksretur [[uttrykk]]; uttrykk Uttrykket hvis verdi vil bli returnert. Hvis ikke spesifisert, returneres udefinert i stedet. Beskrivelse

Når en retursetning kalles i en funksjon, stopper utføringen av den. Den angitte verdien returneres til stedet der funksjonen ble kalt. For eksempel returnerer funksjonen nedenfor den kvadratiske verdien av argumentet, x (der x er et tall):

Funksjon kvadrat(x) ( return x * x; ) var demo = kvadrat(3); // verdi demo vil være 9

Hvis en returverdi ikke er spesifisert, returneres udefinert i stedet.

Følgende uttrykk avbryter alltid utførelsen av en funksjon:

Komme tilbake; return true; returner falsk; returner x; returner x + y / 3;

Plasser automatisk semikolon funksjon magic(x) ( return funksjon calc(x) ( return x * 42 ); ) var answer = magic(); svar(1337); // 56154 Spesifikasjoner Spesifikasjon Status Kommentar
ECMAScript 1. utgave (ECMA-262) Standard Opprinnelig definisjon
ECMAScript 5.1 (ECMA-262)
Standard
ECMAScript 2015 (6. utgave, ECMA-262)
Definisjon av "Returerklæring" i denne spesifikasjonen.
Standard
ECMAScript siste utkast (ECMA-262)
Definisjon av "Returerklæring" i denne spesifikasjonen.
Utkast
Nettleserkompatibilitet

Kompatibilitetstabellen på denne siden er generert fra strukturerte data. Hvis du ønsker å bidra til dataene, kan du hente dem fra depotet https://github.com/mdn/browser-compat-data og sende oss en pull-forespørsel for endringene dine.

Oppdater kompatibilitetsdata på GitHub

Datamaskiner Mobile Server Chrome Edge Firefox Internet Explorer Opera Safari Android webvisning Chrome for Android Firefox for Android Opera for Android Safari på iOS Samsung Internet Node.jskomme tilbake
Chrome Full støtte 1 Edge Full 12-støtteFirefox Full støtte 1IE Full støtte 3Opera Full støtte JaSafari Full støtte JaWebView Android Full støtte 1Chrome Android Full støtte 18Firefox Android Full 4-støtteOpera Android Full støtte JaSafari iOS Full støtte JaSamsung Internet Android Full støtte 1.0nodejs Full støtte Ja

Funksjoner er en av de viktigste byggesteinene for kode i JavaScript.

Funksjoner består av et sett med kommandoer og utfører vanligvis én spesifikk oppgave (for eksempel summere tall, beregne røtter osv.).

Kode plassert i en funksjon vil kun bli utført etter et eksplisitt kall til denne funksjonen.

Funksjonserklæring

1. Syntaks:

//Deklarasjon av funksjonen funksjonFunksjonsnavn(ln1, ln2)( Funksjonskode) //Kaller funksjonenFunksjonsnavn(ln1,lr2);

2. Syntaks:

//Deklarasjon av funksjonen var funksjonsnavn=funksjon(ln1, ln2)(Funksjonskode) //Kaller funksjonen funksjonsnavn(ln1,lr2);

funksjonsnavn angir navnet på funksjonen. Hver funksjon på siden må ha et unikt navn. Funksjonsnavnet må angis med latinske bokstaver og bør ikke starte med tall.

ln1 og ln2 er variabler eller verdier som kan overføres til funksjonen. Et ubegrenset antall variabler kan sendes til hver funksjon.

Vennligst merk: selv om ingen variabler sendes til funksjonen, ikke glem å sette inn parentes "()" etter funksjonsnavnet.

Vær oppmerksom på at funksjonsnavn i JavaScript skiller mellom store og små bokstaver.

Eksempel på JavaScript-funksjon

MessageWrite()-funksjonen i eksemplet nedenfor vil bare bli utført etter at knappen er klikket.

Merk at dette eksemplet bruker onclick-hendelsen. JavaScript-hendelser vil bli dekket i detalj senere i denne opplæringen.

// Funksjonen skriver tekst til sidefunksjonen messageWrite() ( document.write("Denne teksten ble skrevet til siden med JavaScript!"); )

Sende variabler til funksjoner

Du kan sende et ubegrenset antall variabler til funksjoner.

Vær oppmerksom på: alle manipulasjoner med variabler inne i funksjoner utføres faktisk ikke på variablene selv, men på kopien deres, så innholdet i variablene i seg selv endres ikke som et resultat av å utføre funksjoner.

/* La oss definere en funksjon som legger til 10 til den beståtte variabelen og viser resultatet på siden */ funksjon pluss(a)( a=a+10; document.write("Funksjonsutgang: " + a+"
"); ) var a=25; document.write("Verdien av variabelen før funksjonskallet: "+a+"
"); // Kall funksjonen ved å gi den variabelen a pluss(a); document.write("Verdi av variabelen etter å ha kalt funksjonen: "+a+"
");

Hurtigvisning

For å få tilgang til en global variabel fra en funksjon i stedet for en kopi av den, bruk window.variable_name.

Funksjon pluss(a)( vindu.a=a+10; ) var a=25; document.write("Verdien av variabelen før funksjonskallet: "+a+"
"); pluss(a); document.write("Verdi av variabelen etter å ha kalt funksjonen: "+a+"
");

Hurtigvisning

returkommando

Med returkommandoen kan du returnere verdier fra funksjoner.

//Sumfunksjonen returnerer summen av variablene som er sendt til den funksjonen sum(v1,v2)( return v1+v2; ) document.write("5+6=" + sum(5,6) + "
"); document.write("10+4=" + sum(10,4) + "
");

Hurtigvisning

Innebygde funksjoner

I tillegg til brukerdefinerte funksjoner har JavaScript også innebygde funksjoner.

For eksempel lar den innebygde isFinite-funksjonen deg sjekke om den beståtte verdien er et gyldig tall.

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90.33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("Dette er en streng")+"
");

Hurtigvisning

Merk: full liste Du kan finne innebygde JavaScript-funksjoner i vår .

Lokale og globale variabler

Variabler opprettet i funksjoner kalles lokale variabler. Du kan bare få tilgang til slike variabler innenfor funksjonene der de ble definert.

Etter at funksjonskoden er fullført, blir slike variabler ødelagt. Dette betyr at variabler med samme navn kan defineres i forskjellige funksjoner.

Variabler som er opprettet utenfor funksjonskoden kalles globale variabler; slike variabler kan nås fra hvor som helst i koden.

Hvis du erklærer en variabel uten var inne i en funksjon, blir den også global.

Globale variabler blir ødelagt først etter at siden er lukket.

//Deklarer globale variabler var1 og var2 var var1="var1 eksisterer"; var var2; funksjon func1() ( //Tilordne var2 en verdi inne i funksjonen func1 var var2="var2 eksisterer"; ) //Fra en annen funksjon, skriv ut innholdet i variabelen var1 og var2 til sidefunksjonen func2() ( //Skriv ut innholdet i variabelen var1 document.write( var1 + "
"); //Skriv ut innholdet i variabelen var2 document.write(var2); )

Hurtigvisning

Merk at når den skrives ut på skjermen, vil var2 ha en tom verdi fordi func1 opererer på den lokale "versjonen" av var2.

Bruk av anonyme funksjoner

Funksjoner som ikke inneholder navn når de deklareres, kalles anonyme.

Anonyme funksjoner er i utgangspunktet erklært å ikke kalles fra kode som vanlige funksjoner, men sendes til andre funksjoner som en parameter.

Funksjon arrMap(arr,func)( var res=ny matrise; for (var i=0;i


Topp