funkcije JavaScript. Ekspresivni JavaScript: Funkcije Funkcije kot vrednosti

Ljudje mislijo, da je računalništvo umetnost za genije. V resnici je ravno nasprotno – le veliko ljudi počne stvari, ki stojijo ena na drugi, kot da bi sestavljale steno iz majhnih kamenčkov.

Donald Knuth

Videli ste že klice funkcij, kot je opozorilo. Funkcije so kruh in maslo programiranja JavaScript. Zamisel, da bi del programa zavili in ga poklicali kot spremenljivko, je zelo priljubljena. Je orodje za strukturiranje velikih programov, zmanjšanje ponavljanja, dodeljevanje imen podprogramom in izolacijo podprogramov drug od drugega.

Najbolj očitna uporaba funkcij je ustvarjanje novega slovarja. Izmišljanje besed za običajno človeško prozo je slaba oblika. V programskem jeziku je to nujno.

Povprečen odrasel govorec ruščine pozna približno 10.000 besed. Redek programski jezik vsebuje 10.000 vgrajenih ukazov. In besednjak programskega jezika je bolj jasno definiran, zato je manj prilagodljiv kot človeški. Zato mu moramo običajno dodati svoje besede, da se izognemo nepotrebnemu ponavljanju.

Definicija funkcije

Definicija funkcije je običajna definicija spremenljivke, kjer je vrednost, ki jo prejme spremenljivka, funkcija. Naslednja koda na primer definira spremenljivko kvadrat, ki se nanaša na funkcijo, ki izračuna kvadrat danega števila:

var square = function(x) ( return x * x; ); console.log(kvadrat(12)); // → 144

Funkcijo ustvari izraz, ki se začne s ključno besedo function. Funkcije imajo nabor parametrov (v tem primeru samo x) in telo, ki vsebuje navodila, ki jih je treba izvesti ob klicu funkcije. Telo funkcije je vedno v zavitih oklepajih, tudi če je sestavljena iz enega samega stavka.

Funkcija ima lahko več parametrov ali pa nobenega. V naslednjem primeru makeNoise nima seznama parametrov, medtem ko ima power dva:

Var makeNoise = function() ( console.log("Fuck!"); ); naredi hrup (); // → Sranje! var. moč = funkcija (osnova, eksponent) ( sprem. rezultat = 1; for (var. št. = 0; št.< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

Nekatere funkcije vrnejo vrednost, na primer power in square, druge pa ne, na primer makeNoise, ki ima le stranski učinek. Stavek return definira vrednost, ki jo vrne funkcija. Ko programska obdelava doseže to navodilo, takoj zapusti funkcijo in vrne to vrednost na mesto v kodi, od koder je bila funkcija poklicana. return brez izraza vrne nedefinirano.

Parametri in obseg

Funkcijski parametri so tako kot spremenljivke, vendar so njihove začetne vrednosti nastavljene ob klicu funkcije in ne v njeni kodi.

Pomembna lastnost funkcij je, da so spremenljivke, ustvarjene znotraj funkcije (vključno s parametri), lokalne znotraj te funkcije. To pomeni, da bo v primeru moči spremenljivka rezultat ustvarjena vsakič, ko je funkcija poklicana, te njene ločene inkarnacije pa med seboj niso na noben način povezane.

Ta lokalizacija spremenljivk velja le za parametre in spremenljivke, ustvarjene znotraj funkcij. Spremenljivke, nastavljene zunaj katere koli funkcije, imenujemo globalne spremenljivke, ker so vidne v celotnem programu. Do takšnih spremenljivk lahko dostopate tudi znotraj funkcije, razen če ste deklarirali lokalno spremenljivko z istim imenom.

Naslednja koda to ponazarja. Definira in kliče dve funkciji, ki dodelita vrednost x. Prvi ga razglasi za lokalnega in s tem spremeni samo lokalno spremenljivko. Drugi ne deklarira, zato se delo z x znotraj funkcije nanaša na globalno spremenljivko x, ki je bila nastavljena na začetku primera.

var x = "zunaj"; var f1 = function() ( var x = "znotraj f1";); f1(); dnevnik konzole(x); // → zunaj var f2 = funkcija() ( x = "znotraj f2"; ); f2(); dnevnik konzole(x); // → znotraj f2

To vedenje pomaga preprečiti nenamerno interakcijo med funkcijami. Če bi bile vse spremenljivke uporabljene kjerkoli v programu, bi bilo zelo težko zagotoviti, da ena spremenljivka ni uporabljena za različne namene. In če bi znova uporabili spremenljivko, bi naleteli na čudne učinke, ko se koda tretjih oseb zamoti z vrednostmi vaše spremenljivke. Z obravnavanjem funkcijskih lokalnih spremenljivk tako, da obstajajo le znotraj funkcije, jezik omogoča delo s funkcijami, kot da bi bile ločene majhne vesolje, kar vam omogoča, da ne skrbite za celotno kodo kot celoto.

Ugnezdeni obsegi

JavaScript ne razlikuje samo med globalnimi in lokalnimi spremenljivkami. Funkcije je mogoče definirati znotraj funkcij, kar povzroči več ravni lokalnosti.

Naslednja precej nesmiselna funkcija na primer vsebuje še dve:

var landscape = function() ( var result = ""; var flat = function(size) ( for (var count = 0; count< 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()); // → ___/""""\______/"\_

Ravne in gorske funkcije vidijo spremenljivko rezultata, ker so znotraj funkcije, v kateri je definirana. Vendar ne moreta videti spremenljivk štetja drug drugega, ker so spremenljivke ene funkcije zunaj obsega druge. In okolje zunaj ležeče funkcije ne vidi nobene od spremenljivk, definiranih znotraj te funkcije.

Skratka, v vsakem lokalnem obsegu si lahko ogledate vse obsege, ki ga vsebujejo. Nabor spremenljivk, ki so na voljo znotraj funkcije, je določen z mestom, kjer je ta funkcija deklarirana v programu. Vse spremenljivke iz blokov, ki obkrožajo definicijo funkcije, so vidne - vključno s tistimi, ki so definirane na najvišji nivo v glavnem programu. Ta pristop k obsegom se imenuje leksikalni.

Ljudje, ki so študirali druge programske jezike, bi morda mislili, da vsak blok, zaprt v zavitih oklepajih, ustvarja svoje lokalno okolje. Toda v JavaScriptu samo funkcije ustvarijo obseg. Uporabite lahko samostojne bloke:

var nekaj = 1; ( var something = 2; // Naredi nekaj s spremenljivko something ... ) // Izhod iz bloka ...

Toda nekaj znotraj bloka je ista spremenljivka kot zunaj. Čeprav so takšni bloki dovoljeni, jih je smiselno uporabljati samo za stavke if in zanke.

Če se vam to zdi čudno, se ne zdi tako samo vam. JavaScript 1.7 je uvedel ključno besedo let, ki deluje kot var, vendar ustvarja spremenljivke, ki so lokalne za kateri koli blok, ne le za funkcijo.

Funkcije kot vrednote

Imena funkcij se običajno uporabljajo kot imena za del programa. Takšna spremenljivka je enkrat nastavljena in se ne spreminja. Funkcijo je torej enostavno zamenjati z njenim imenom.

Ampak to sta dve različni stvari. Klic funkcije je mogoče uporabiti kot preprosto spremenljivko – na primer, uporabiti jih je mogoče v katerem koli izrazu. Klic funkcije je mogoče shraniti v novo spremenljivko, jo posredovati kot parameter drugi funkciji itd. Tudi spremenljivka, ki shrani klic funkcije, ostane navadna spremenljivka in njeno vrednost je mogoče spremeniti:

Var launchMissiles = funkcija(vrednost) (​missileSystem. launch("prosim!");); if (safeMode) launchMissiles = function(value) (/* release */);

V 5. poglavju bomo razpravljali o čudovitih stvareh, ki jih lahko naredimo s posredovanjem funkcijskih klicev drugim funkcijam.

Deklaracija funkcije

Obstaja krajša različica izraza »var square = function…«. Ključno besedo funkcije lahko uporabite na začetku stavka:

funkcija square(x) ( return x * x; )

To je deklaracija funkcije. Stavek definira spremenljivko square in ji dodeli dano funkcijo. Zaenkrat je vse ok. V taki definiciji je samo ena past.

Console.log("Prihodnost pravi:", future()); function future() ( return "ŠE VEDNO nimamo letečih avtomobilov."; )

Ta koda deluje, čeprav je funkcija deklarirana pod kodo, ki jo uporablja. To je zato, ker deklaracije funkcij niso del običajnega izvajanja programov od zgoraj navzdol. "Premaknejo" se na vrh svojega obsega in jih lahko pokliče katera koli koda v tem obsegu. To je včasih priročno, ker lahko kodo napišete v vrstnem redu, ki je najbolj smiseln, ne da bi vam bilo treba skrbeti, da bi morali definirati vse zgoraj navedene funkcije, kjer se uporabljajo.

Toda kaj se zgodi, če deklaracijo funkcije postavimo znotraj pogojnega bloka ali zanke? Tega ti ni treba narediti. V preteklosti so različne platforme za izvajanje JavaScripta obravnavale takšne primere različno, trenutni jezikovni standard pa to prepoveduje. Če želite, da se vaši programi izvajajo dosledno, uporabite deklaracije funkcij samo znotraj drugih funkcij ali glavnega programa.

Primer funkcije() ( funkcija a() () // Normule if (nekaj) ( funkcija b() () // Ay-yy-yy! ) )

klicni sklad
Koristno je, če si podrobneje ogledamo, kako izvršilni vrstni red deluje s funkcijami. Tukaj preprost program z več klici funkcij:

Funkcija greet(who) ( console.log("Živjo, " + kdo); ) greet("Semyon"); console.log("Pokeda");

Obdeluje se nekako takole: klic greet povzroči, da prehod skoči na začetek funkcije. Pokliče vgrajeno funkcijo console.log, ki prevzame nadzor, opravi svoje in vrne nadzor. Nato doseže konec pozdrava in se vrne na mesto, od koder je bil poklican. Naslednja vrstica znova pokliče console.log.

Shematično je to mogoče prikazati na naslednji način:

Top pozdravi console.log pozdravi zgoraj console.log top

Ker se mora funkcija vrniti tja, od koder je bila poklicana, si mora računalnik zapomniti kontekst, iz katerega je bila funkcija poklicana. V enem primeru bi se moral console.log spremeniti nazaj v pozdrav. V drugem se vrne na konec programa.

Mesto, kjer si računalnik zapomni kontekst, se imenuje sklad. Ob vsakem klicu funkcije je trenutni kontekst potisnjen na vrh sklada. Ko se funkcija vrne, odstrani zgornji kontekst iz sklada in ga uporabi za nadaljevanje.

Skladiščenje zahteva prostor v pomnilniku. Ko sklad postane prevelik, računalnik preneha z izvajanjem in izda nekaj podobnega kot "stack overflow" ali "preveč rekurzije". Naslednja koda to prikazuje - računalniku postavi zelo kompleksno vprašanje, ki vodi do neskončnih skokov med dvema funkcijama. Natančneje, šlo bi za neskončne skoke, če bi imel računalnik neskončen sklad. V resnici se sklad preliva.

Funkcija chicken() ( return egg(); ) function egg() ( return chicken(); ) console.log(chicken() + " je bil prvi."); // → ??

Izbirni argumenti
Naslednja koda je popolnoma zakonita in deluje brez težav:

Opozorilo ("Pozdravljeni", "Dober večer", "Pozdravljeni vsi!");

Uradno funkcija sprejme en argument. Vendar se ob takšnem izzivu ne pritožuje. Prezre preostale argumente in prikaže "Pozdravljeni".

JavaScript je zelo popustljiv glede števila argumentov, posredovanih funkciji. Če podate preveč, bodo dodatni prezrti. Premalo – manjkajočim bo dodeljena vrednost nedefinirana.

Pomanjkljivost tega pristopa je, da je možno – in celo verjetno –, da funkciji posredujete napačno število argumentov, zaradi česar se vam ne bo nihče pritoževal.

Prednost je, da lahko ustvarite funkcije, ki sprejemajo neobvezne argumente. Na primer, v naslednji različici potenčne funkcije jo lahko pokličemo z dvema in enim argumentom – v slednjem primeru bo eksponent enak dve, funkcija pa deluje kot kvadrat.

Funkcijska moč (osnova, eksponent) ( if (eksponent == nedefinirano) eksponent = 2; sprem. rezultat = 1; for (var count = 0; count< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

V naslednjem poglavju bomo videli, kako vam lahko telo funkcije pove natančno število argumentov, ki so ji bili posredovani. To je koristno, ker omogoča ustvarjanje funkcije, ki sprejme poljubno število argumentov. Na primer, console.log uporablja to lastnost in natisne vse argumente, ki so mu bili posredovani:

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

Zapirala

Zmožnost uporabe funkcijskih klicev kot spremenljivk, skupaj z dejstvom, da se lokalne spremenljivke znova ustvarijo vsakič, ko je funkcija poklicana, nas pripelje do zanimive točke. Kaj se zgodi z lokalnimi spremenljivkami, ko funkcija odpove?

Naslednji primer ponazarja to težavo. Deklarira funkcijo wrapValue, ki ustvari lokalno spremenljivko. Nato vrne funkcijo, ki prebere to lokalno spremenljivko in vrne njeno vrednost.

Funkcija wrapValue(n) ( var localVariable = n; return function() ( return localVariable; ); ) var wrap1 = wrapValue(1); var wrap2 = wrapValue(2); dnevnik konzole (wrap1()); // → 1 console.log(wrap2()); // → 2

To je veljavno in deluje kot mora - dostop do spremenljivke ostane. Poleg tega lahko istočasno obstaja več primerkov iste spremenljivke, kar dodatno potrjuje dejstvo, da se lokalne spremenljivke znova ustvarijo z vsakim klicem funkcije.

Ta zmožnost dela s sklicevanjem na neko instanco lokalne spremenljivke se imenuje zaprtje. Funkcija, ki zapre lokalne spremenljivke, se imenuje zapiralna funkcija. Ne le, da vas osvobodi skrbi glede spremenljivih življenjskih dob, omogoča vam tudi ustvarjalno uporabo funkcij.

Z majhno spremembo naš primer spremenimo v funkcijo, ki množi števila s poljubnim številom.

Funkcija množitelj(faktor) ( vrni funkcijo(število) ( vrni število * faktor; ); ) var dvakrat = množitelj(2); console.log(dvakrat(5)); // → 10

Ločena spremenljivka, kot je localVariable iz primera wrapValue, ni več potrebna. Ker je parameter sam lokalna spremenljivka.

Potrebna je praksa, da začneš tako razmišljati. Dobra različica mentalnega modela je predstavljati, da funkcija zamrzne kodo v svojem telesu in jo zavije v paket. Ko vidite return function(...) (...), si predstavljajte to kot nadzorno ploščo za kos kode, ki je zamrznjen za kasnejšo uporabo.

V našem primeru množitelj vrne zamrznjen del kode, ki ga shranimo v spremenljivko two. Zadnja vrstica pokliče funkcijo v spremenljivki, ki aktivira shranjeno kodo (povratna številka * faktor;). Še vedno ima dostop do faktorske spremenljivke, ki je bila definirana ob klicu množitelja, in ima tudi dostop do argumenta, posredovanega med odmrzovanjem (5) kot številski parameter.

rekurzija

Funkcija lahko pokliče sama sebe, če pazi, da ne prepolni sklada. Takšna funkcija se imenuje rekurzivna. Tukaj je primer alternativne izvedbe stopnjevanja:

Funkcija power(osnova, eksponent) ( if (eksponent == 0) vrne 1; sicer vrne osnovo * power(osnova, eksponent - 1); ) console.log(power(2, 3)); // → 8

Tako matematiki definirajo potenciranje in morda to bolj elegantno opiše koncept kot cikel. Funkcija se večkrat pokliče z različnimi argumenti, da doseže večkratno množenje.

Vendar ima ta izvedba težavo – v običajnem okolju JavaScript je 10-krat počasnejša od različice z zanko. Vrnitev v zanko je cenejša od klicanja funkcije.

Dilema hitrost proti eleganci je zelo zanimiva. Obstaja določen razkorak med udobjem ljudi in udobjem strojev. Vsak program je mogoče pospešiti tako, da ga naredimo večjega in bolj zapletenega. Programer mora najti pravo ravnotežje.

V primeru prvega potenciranja je neelegantna zanka precej preprosta in enostavna. Nima smisla zamenjati z rekurzijo. Pogosto pa programi delajo s tako zapletenimi koncepti, da želimo zmanjšati učinkovitost s povečanjem berljivosti.

Osnovno pravilo, ki je bilo večkrat ponovljeno in s katerim se popolnoma strinjam - ne skrbite za delovanje, dokler niste prepričani, da se program upočasnjuje. Če je tako, poiščite dele, ki trajajo najdlje, in tam zamenjajte eleganco za učinkovitost.

Seveda pa ne smemo kar takoj zanemariti uspešnosti. V mnogih primerih, tako kot pri potenciranju, z elegantnimi rešitvami ne dobimo veliko preprostosti. Včasih izkušen programer takoj vidi, da preprost pristop nikoli ne bo dovolj hiter.

To omenjam, ker se preveč programerjev začetnikov oklepa učinkovitosti že pri majhnih stvareh. Rezultat je večji, bolj zapleten in pogosto ne brez napak. Takšni programi se pišejo dlje in pogosto ne delujejo veliko hitreje.

Toda rekurzija ni vedno le manj učinkovita alternativa zankam. Nekatere probleme je lažje rešiti z rekurzijo. Najpogosteje je to prečenje več drevesnih vej, od katerih se lahko vsaka razveji.

Tukaj je uganka za vas: dobite lahko neskončno število števil, začenši s številko 1, nato pa dodate 5 ali pomnožite s 3. Kako napišemo funkcijo, ki skuša po določenem številu najti zaporedje takih seštevanja in množenja, ki vodijo do danega števila? Na primer, število 13 lahko dobite tako, da najprej pomnožite 1 s 3 in nato dvakrat dodate 5. In številke 15 je na splošno nemogoče dobiti tako.

Rekurzivna rešitev:

Function findSolution(target) ( function find(start, history) ( if (start == target) vrni zgodovino; else if (start > target) vrni nič; sicer vrni find(start + 5, "(" + history + " + 5)") || find(start * 3, "(" + history + " * 3)"); ) return find(1, "1"); ) console.log(findSolution(24)); // → (((1 * 3) + 5) * 3)

Ta primer ne najde nujno najkrajše rešitve - zadovolji vsako. Ne pričakujem, da boste takoj razumeli, kako program deluje. Toda pojdimo tej odlični vaji rekurzivnega razmišljanja do dna.

Iskanje notranje funkcije je rekurzivno. Potrebuje dva argumenta - trenutno številko in niz, ki vsebuje zapis o tem, kako smo prišli do te številke. In vrne niz, ki prikazuje naše zaporedje korakov, ali nič.

Za to funkcija izvede eno od treh dejanj. Če je podana številka enaka cilju, potem je trenutna zgodovina samo pot do cilja, zato se vrne. Če je dano število večje od ciljnega, nima smisla nadaljevati z množenjem in seštevanjem, saj se bo tako le še povečalo. In če cilja še nismo dosegli, funkcija poskusi obe možni poti, začenši od podane številke. Dvakrat se prikliče, po enkrat z vsakim načinom. Če prvi klic vrne ni ničelno, se vrne. V nasprotnem primeru se drugi vrne.

Da bi bolje razumeli, kako funkcija doseže želeni učinek, si poglejmo njene klice, ki se pojavijo pri iskanju rešitve za številko 13.

Najdi (1, "1") najdi (6, "(1 + 5)") najdi (11, "((1 + 5) + 5)") najdi (16, "(((1 + 5) + 5 ) + 5)") prevelika najdba(33, "(((1 + 5) + 5) * 3)") prevelika najdba(18, "((1 + 5) * 3)") prevelika najdba( 3, "(1 * 3)") najdi (8, "((1 * 3) + 5)") najdi (13, "(((1 * 3) + 5) + 5)") najdeno!

Vdolbina prikazuje globino sklada klicev. Prvič se funkcija iskanja dvakrat pokliče, da preveri rešitve, ki se začnejo z (1 + 5) in (1 * 3). Prvi klic išče rešitev, ki se začne z (1 + 5), in uporablja rekurzijo za preverjanje vseh rešitev, ki dajejo število, ki je manjše ali enako želenemu številu. Ne najde in vrne nič. Nato operator || in skoči na klic funkcije, ki preuči možnost (1 * 3). Tu imamo srečo, saj jih v tretjem rekurzivnem klicu dobimo 13. Ta klic vrne niz in vsak od || med potjo posreduje ta zgornji niz in kot rezultat vrne rešitev.

Funkcije rasti

Obstajata dva bolj ali manj naravna načina za vnos funkcij v program.

Najprej večkrat napišete podobno kodo. Temu se je treba izogibati – več kode pomeni več prostora za napake in več bralnega gradiva za tiste, ki poskušajo razumeti program. Zato vzamemo ponavljajočo se funkcionalnost, ji damo dobro ime in jo postavimo v funkcijo.

Drugi način je, da odkrijete potrebo po neki novi funkcionalnosti, ki je vredna, da bi jo postavili v ločeno funkcijo. Začnete z imenom funkcije in nato napišete njeno telo. Začnete lahko celo tako, da napišete kodo, ki uporablja funkcijo, preden je funkcija sama definirana.

Kako težko vam je poimenovati funkcijo, kaže, kako dobro razumete njeno funkcionalnost. Vzemimo primer. Napisati moramo program, ki izpiše dve števili, število krav in piščancev na kmetiji, ki jima sledi besedi "krave" in "piščanci". Številkam pred njimi morate dodati ničle, tako da bo vsaka zasedla natanko tri mesta.

007 Krave 011 Kokoši

Očitno potrebujemo funkcijo z dvema argumentoma. Začnimo s kodiranjem.
// printFarmInventory funkcija printFarmInventory(krave, piščanci) ( var cowString = String(cows); medtem ko (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);

Če nizu dodamo .length, dobimo njegovo dolžino. Izkazalo se je, da zanke while številkam dodajajo vodilne ničle, dokler ne dobijo niza treh znakov.

pripravljena! Toda takoj, ko smo tik pred tem, da kmetu pošljemo šifro (seveda z zajetnim čekom), nas pokliče in pove, da ima na kmetiji prašiče in ali lahko dodamo izpis števila prašičev. v program?

Seveda je možno. Toda ko začnemo kopirati in lepiti kodo iz teh štirih vrstic, ugotovimo, da se moramo ustaviti in razmisliti. Mora obstajati boljši način. Trudimo se izboljšati program:

// funkcija outputZeroPaddedWithLabel printZeroPaddedWithLabel(number, label) ( var numberString = String(number); 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);

deluje! Toda ime printZeroPaddedWithLabel je nekoliko čudno. Združuje tri stvari - izpis, ničelno polnjenje in oznako - v eno funkcijo. Namesto da bi celoten ponavljajoči se fragment stlačili v funkcijo, poudarimo en koncept:

// dodajanje funkcije Zeros zeroPad(number, width) ( var string = String(number); 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);

Funkcija z lepim, opisnim imenom zeroPad olajša razumevanje kode. In lahko se uporablja v mnogih situacijah, ne samo v našem primeru. Na primer za prikaz oblikovanih tabel s številkami.

Kako pametne in vsestranske naj bodo funkcije? Napišemo lahko preprosto funkcijo, ki številko dopolni z ničlami ​​do treh položajev, pa tudi modno funkcijo splošnega namena za oblikovanje števil, ki podpira ulomke, negativna števila, poravnavo pik, polnjenje z različnimi znaki itd.

Dobro pravilo je, da dodate samo tiste funkcije, ki jih zagotovo potrebujete. Včasih je skušnjava ustvariti splošne okvire za vsako najmanjšo potrebo. Uprite se mu. Nikoli ne boste dokončali dela, ampak samo napisali kup kode, ki je nihče ne bo uporabil.

Funkcije in stranski učinki

Funkcije lahko v grobem razdelimo na tiste, ki so priklicane zaradi stranskih učinkov, in tiste, ki so priklicane, da bi pridobile neko vrednost. Seveda je možno tudi združiti te lastnosti v eni funkciji.

Prva pomožna funkcija v primeru farme, printZeroPaddedWithLabel, je poklicana zaradi stranskega učinka tiskanja niza. Drugi, zeroPad, zaradi vrnjene vrednosti. In ni naključje, da druga funkcija pride prav pogosteje kot prva. Funkcije, ki vrnejo vrednosti, je lažje kombinirati med seboj kot funkcije, ki ustvarjajo stranske učinke.

Čista funkcija je posebna vrsta funkcije za vračanje vrednosti, ki nima samo stranskih učinkov, ampak tudi ni odvisna od stranskih učinkov preostale kode – na primer ne deluje z globalnimi spremenljivkami, ki jih je mogoče pomotoma spremeniti nekje drugje. Čista funkcija, ko je poklicana z istimi argumenti, vrne enak rezultat (in ne naredi nič drugega) - kar je zelo lepo. Z njo je enostavno delati. Klic takšne funkcije je mogoče mentalno nadomestiti z rezultatom njenega dela, ne da bi spremenili pomen kode. Ko želite preizkusiti takšno funkcijo, jo lahko preprosto pokličete in ste prepričani, da če deluje v tem kontekstu, bo delovala tudi v katerem koli. Ne tako čiste funkcije lahko vrnejo različne rezultate, odvisno od številnih dejavnikov, in imajo stranske učinke, ki jih je težko preizkusiti in upoštevati.

Vendar se ne smete sramežljivo pisati funkcij, ki niso povsem čiste, ali začeti svetega čiščenja kode iz takih funkcij. Stranski učinki so pogosto koristni. Čiste različice funkcije console.log ni mogoče napisati, ta funkcija pa je zelo uporabna. Nekatere operacije je lažje izraziti s stranskimi učinki.

Izid

To poglavje vam je pokazalo, kako napišete lastne funkcije. Ko je ključna beseda funkcije uporabljena kot izraz, vrne kazalec na klic funkcije. Ko jo uporabljate kot stavek, lahko deklarirate spremenljivko tako, da ji dodelite klic funkcije.

Ključ do razumevanja funkcij so lokalni obsegi. Parametri in spremenljivke, deklarirane znotraj funkcije, so lokalni zanjo, znova ustvarjeni ob vsakem klicu in niso vidni od zunaj. Funkcije, deklarirane znotraj druge funkcije, imajo dostop do njenega obsega.

Zelo koristno je razdeliti različne naloge, ki jih izvaja program, na funkcije. Ni se vam treba ponavljati, funkcije naredijo kodo bolj berljivo, tako da jo ločijo na semantične dele, na enak način, kot poglavja in deli knjige pomagajo organizirati golo besedilo.

vaje

Najmanjša
V prejšnjem poglavju je bila omenjena funkcija Math.min, ki vrne najmanjši argument. Zdaj lahko takšno funkcijo napišemo sami. Pišite funkcija min A, ki sprejme dva argumenta in vrne najmanjšega od njiju.

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

rekurzija
Videli smo, da lahko operator % (ostanek) uporabimo za ugotavljanje, ali je število sodo (% 2). Tukaj je še en način za določitev:

Nič je sodo.
Enota je čudna.
Vsako število N ima enako pariteto kot N-2.

Napišite rekurzivno funkcijo isEven v skladu s temi pravili. Vzeti mora število in vrniti logično vrednost.

Preizkusite na 50 in 75. Poskusite dati -1. Zakaj se tako obnaša? Ali je to mogoče nekako popraviti?

Preizkusite ga na 50 in 75. Poglejte, kako se obnaša na -1. Zakaj? Ali lahko mislite, kako bi to popravili?

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

Štejemo fižol.

Število znakov N niza lahko dobite tako, da mu dodate .charAt(N)("string".charAt(5)) na podoben način, kot bi dobili dolžino niza z .length. Vrnjena vrednost bo niz z enim znakom (na primer "k"). Prvi znak niza ima položaj 0, kar pomeni, da zadnji znak pozicija bo string.length - 1. Z drugimi besedami, niz z dvema znakoma bo imel dolžino 2, njegova položaja znakov pa bosta 0 in 1.

Napišite funkcijo countBs, ki vzame niz kot argument in vrne število znakov »B« v nizu.

Nato napišite funkcijo countChar, ki deluje podobno kot countB, le da sprejme drugi parameter, znak, ki ga bomo iskali v nizu (namesto samo štetja števila znakov "B"). Če želite to narediti, prepišite funkcijo countBs.

Preskočni stavki in obravnava izjem

Druga kategorija jezikovnih operaterjev JavaScript so operatorji skokov. Kot že ime pove, ti stavki povzročijo, da tolmač JavaScript skoči na drugo mesto v programski kodi. Stavek break povzroči, da tolmač skoči na konec zanke ali drugega stavka. Stavek continue povzroči, da tolmač preskoči preostali del telesa zanke, skoči nazaj na začetek zanke in začne novo ponovitev. JavaScript ima možnost označevanja stavkov z imeni, tako da je stavkom prekinitev in nadaljevanje mogoče izrecno navesti, kateri zanki ali drugemu stavku pripadajo.

Stavek return povzroči, da tolmač skoči s klicane funkcije nazaj na točko, kjer je bila klicana, in vrne vrednost klica. Stavek vrzi sproži izjemo in je zasnovan tako, da deluje v povezavi s stavki poskusi/ulovi/končno, ki definirajo blok kode za obravnavo izjeme. To je precej zapletena vrsta stavkov o skoku: ko pride do izjeme, tolmač skoči na najbližji obkrožajoči obravnavalec izjeme, ki je lahko v isti funkciji ali višji, na povratnem skladu klicane funkcije.

Vsak od teh operatorjev skokov je podrobneje opisan v naslednjih pododdelkih.

Oznake z navodili

Vsak stavek je lahko označen z identifikatorjem in dvopičjem pred njim:

identifikator: navodilo

Ko označite navodilo, mu daste ime, ki ga lahko nato uporabite kot referenco kjer koli v programu. Označite lahko katero koli navodilo, vendar je smiselno označiti le navodila, ki imajo telo, kot so zanke in pogojni stavki.

Če zanki daste ime, jo lahko nato uporabite v stavkih break in continue, znotraj zanke za izhod iz nje ali za skok na začetek zanke, na naslednjo ponovitev. Stavka break in continue sta edina stavka v jeziku JavaScript, ki lahko vsebujeta oznake – o njih bomo podrobneje razpravljali kasneje. Sledi primer stavka while z oznako in stavka continue, ki uporablja to oznako:

Glavna zanka: medtem (token != null) ( // Programska koda je izpuščena ... nadaljuj z glavno zanko; // Pojdi na naslednjo ponovitev imenovane zanke )

Identifikator, uporabljen kot oznaka stavka, je lahko kateri koli veljaven identifikator JavaScript, razen rezervirane besede. Imena oznak so ločena od imen spremenljivk in funkcij, tako da lahko kot oznake uporabite identifikatorje, ki se ujemajo z imeni spremenljivk ali funkcij.

Oznake navodil so definirane le znotraj navodil, na katera se nanašajo (in seveda znotraj navodil, ki so v njih ugnezdena). Ugnezdenih navodil ni mogoče označiti z enakimi identifikatorji kot navodila, ki jih vsebujejo, vendar sta lahko dve neodvisni navodili označeni z isto oznako. Označena navodila je mogoče ponovno označiti. To pomeni, da ima lahko vsako navodilo več oznak.

izjava o prekinitvi

Stavek break povzroči, da se najbolj notranja zanka ali stavek switch takoj zapre. Prej smo že videli primere uporabe stavka break znotraj stavka switch. V zankah se običajno uporablja za takojšen izhod iz zanke, ko je iz nekega razloga treba prekiniti izvajanje zanke.

Ko je ciklus zelo zapleteno stanje dokončanje, je te pogoje pogosto lažje implementirati s stavkom za prekinitev, kot pa jih poskušati izraziti v enem pogojniku zanke. Naslednji primer poskuša najti element matrike z določeno vrednostjo. Zanka se konča na običajen način, ko je dosežen konec matrike, ali s stavkom break, takoj ko je najdena želena vrednost:

Var arr = ["a","b","c","d","e"], rezultat; za (var i = 0; i

V JavaScriptu lahko podate ime oznake za ključno besedo break (identifikator brez dvopičja):

break label_name;

Ko je stavek break uporabljen z oznako, skoči na konec imenovanega stavka ali prekine njegovo izvajanje. Če ni ukaza s podano oznako, poskus uporabe te oblike stavka break ustvari sintaktično napako. Ni nujno, da je imenovani stavek zanka ali stavek switch. Označeni prekinitveni stavek lahko "pobegne" iz katerega koli vsebujočega stavka. Obdajajoči stavek je lahko celo preprost blok stavkov, zaprtih v zavitih oklepajih z edinim namenom označevanja.

Znaka za novo vrstico ni mogoče vstaviti med ključno besedo break in ime oznake. To je zato, ker tolmač JavaScript samodejno vstavi manjkajoče podpičje: če prekinete vrstico kode med ključno besedo break in oznako, ki ji sledi, bo tolmač domneval, da ste mislili preprosto obliko tega operatorja brez oznake, in dodal podpičje .

Označeni prekinitveni stavek je potreben le, če želite prekiniti izvajanje stavka, ki ni najbližja obdajajoča zanka ali stavek preklopa.

nadaljevanje izjave

Stavek continue je podoben stavku break. Vendar namesto izhoda iz zanke stavek continue začne novo ponovitev zanke. Sintaksa za stavek continue je tako preprosta kot sintaksa za stavek break. Stavek continue se lahko uporablja tudi z oznako.

Stavek continue, bodisi neoznačen ali označen, je mogoče uporabiti samo v telesu zanke. Če ga uporabite kjer koli drugje, pride do sintaksne napake. Ko se izvede stavek continue, se trenutna ponovitev zanke prekine in začne se naslednja. Za različni tipi cikli pomenijo različne stvari:

    V zanki while se izraz, določen na začetku zanke, znova preveri in če je resničen, se telo zanke izvede od začetka.

    Zanka do/while skoči na konec zanke, kjer se pogoj ponovno preveri, preden se zanka ponovi.

    V zanki for se ovrednoti izraz povečanja in testni izraz se ponovno ovrednoti, da se ugotovi, ali je treba izvesti naslednjo ponovitev.

    V zanki for/in se zanka začne znova in podani spremenljivki dodeli ime naslednje lastnosti.

Upoštevajte razliko v obnašanju stavka continue v zankah while in for. Zanka while se vrne neposredno k svojemu pogoju, medtem ko zanka for najprej ovrednoti izraz prirastka in se nato vrne k pogoju. Naslednji primer prikazuje uporabo neoznačenega stavka za nadaljevanje za izhod iz trenutne ponovitve zanke za soda števila:

spremenljiva vsota = 0; // Izračunajte vsoto lihih števil od 0 do 10 za (var i = 0; i

Stavek continue, tako kot break, se lahko uporablja v ugnezdenih zankah v obliki, ki vključuje oznako, pri čemer ni nujno, da ponovno zagnana zanka takoj vsebuje stavek continue. Poleg tega, tako kot pri prelomu, nove vrstice med ključno besedo continue in imenom oznake niso dovoljene.

izjava o vrnitvi

Klic funkcije je izraz in kot vsi izrazi ima vrednost. Stavek return znotraj funkcij se uporablja za določitev vrednosti, ki jo vrne funkcija. Stavek vrnitve je mogoče postaviti le v telo funkcije. Njegova prisotnost kjerkoli drugje je sintaksna napaka. Ko se izvede stavek return, funkcija vrne vrednost izraza klicnemu programu. Na primer:

Če funkcija nima povratnega stavka, bo tolmač ob klicu izvedel navodila v telesu funkcije enega za drugim, dokler ne doseže konca funkcije, nato pa vrne nadzor programu, ki jo je poklical. V tem primeru bo klicni izraz vrnil nedefiniran. Izjava o vračilu je pogosto zadnje navodilo v funkciji, vendar je to povsem neobvezno: funkcija bo vrnila nadzor klicnemu programu takoj, ko je dosežen povratni stavek, tudi če mu sledijo drugi stavki v telesu funkcije.

Stavek return je mogoče uporabiti tudi brez izraza, v tem primeru preprosto prekine funkcijo in vrne nedefinirano klicatelju. Na primer:

Funkcija myFun(arr) ( // Če matrika vsebuje negativna števila, prekinite funkcijo za (var i = 0; i

vrzi izjavo

Izjema je signal, ki kaže na pojav neke vrste izjeme ali napake. Vzgoja izjeme (vrh) je način za signaliziranje takšne napake ali izjeme. Ujeti izjemo (catch) pomeni obravnavati, tj. sprejeti potrebne ali ustrezne ukrepe za okrevanje po izjemi.

V JavaScriptu se vržejo izjeme, ko pride do napake med izvajanjem in ko jo program izrecno sproži s stavkom vrži. Izjeme se ujamejo s stavki try/catch/finally, ki so opisani kasneje.

Stavek vrzi ima naslednjo sintakso:

vrgel izraz;

Rezultat izraza je lahko vrednost katere koli vrste. Stavku vrzi se lahko posreduje številka, ki predstavlja kodo napake, ali niz, ki vsebuje besedilo sporočila o napaki. Tolmač JavaScript vrže izjeme z uporabo primerka razreda napaka enega od njegovih podrazredov, lahko pa uporabite tudi podoben pristop. Objekt Error ima lastnost ime, ki določa vrsto napake in lastnost sporočilo A, ki vsebuje niz, posredovan funkciji konstruktorja. Sledi primer funkcije, ki ob klicu z neveljavnim argumentom sproži objekt Error:

// Funkcija faktorial števila function factorial(number) ( // Če vhodni argument ni veljavna vrednost, // se vrže izjema! if (število 1; i *= število, število--); /* prazno telo zanke */ return i ; ) konzola.log("5! = ", faktorial(5)); konzola. log("-3! = ", faktorial(-3));

Ko je vržena izjema, tolmač JavaScript takoj prekine normalno izvajanje programa in skoči na najbližjo obravnavo izjeme. Obdelovalci izjem uporabljajo stavek catch konstrukta try/catch/finally, ki je opisan v naslednjem razdelku.

Če blok kode, v katerem je prišlo do izjeme, nima ustrezne konstrukcije catch, tolmač razčleni naslednji zunanji blok kode in preveri, ali je z njim povezan obravnavalec izjem. To se nadaljuje, dokler se ne najde upravljavec.

Če je izjema vržena v funkciji, ki ne vsebuje konstrukcije try/catch/finally za njeno obravnavo, se izjema razširi navzgor v kodo, ki je poklicala funkcijo. Tako se izjeme širijo skozi leksikalno strukturo metod JavaScript navzgor po klicnem skladu. Če obravnavalec izjeme ni nikoli najden, se izjema obravnava kot napaka in se sporoči uporabniku.

poskusi/ulovi/končno zgradi

Konstrukcija try/catch/finally izvaja mehanizem za obravnavanje izjem JavaScripta. poskusi stavek v tem konstruktu preprosto definira blok kode, v katerem se obravnavajo izjeme. Bloku poskusa sledi izjava o ulovu z blokom stavkov, ki jih je treba poklicati, če se kjer koli v poskusnem bloku pojavi izjema. Stavku catch sledi blok končno A, ki vsebuje kodo, ki izvaja končne operacije in je zagotovljeno, da se izvaja ne glede na to, kaj se zgodi v poskusnem bloku.

Oba bloka catch in finally sta neobvezna, vendar mora biti vsaj eden od njiju prisoten po poskusnem bloku. poskusi, ulovi in ​​končno blokira začetek in konec zavit oklepaj. To je obvezen del sintakse in ga ni mogoče izpustiti, tudi če je med njima le en stavek.

Naslednji delček ponazarja sintakso in namen konstrukcije try/catch/finally:

Poskusi ( // Običajno bo ta koda potekala gladko od začetka do konca. // Toda na neki točki lahko vrže izjemo, // neposredno s stavkom vrženja ali posredno, // s klicem metode, ki vrže izjema. ) catch (ex) ( // Stavki v tem bloku se izvedejo, če in samo če pride do izjeme v poskusnem bloku //. Ti stavki lahko uporabljajo lokalno spremenljivko ex, ki se // nanaša na objekt Error ali na drugo vrednost, določena v stavku vrženja. // Ta blok lahko na nek način obravnava izjemo ali // jo ignorira in naredi nekaj drugega ali // ponovno vrže izjemo s stavkom vrženja. ) končno ( // Ta blok vsebuje stavke ki se vedno izvedejo, ne glede na to, ali , // kaj se je zgodilo v poskusnem bloku. Izvedejo se, če se poskusni blok konča: // 1) kot običajno, doseže konec bloka // 2) zaradi prekinitve, nadaljevanja ali vrnitve izjave // ​​3) z izjemo, ki jo obravnava v bloku catch zgoraj // ​​4) z neujeto izjemo, ki se še naprej // širi na višje ravni)

Upoštevajte, da ključni besedi catch sledi identifikator v oklepaju. Ta identifikator je podoben funkcijskemu parametru. Ko je izjema ujeta, bo ta parameter nastavljen na izjemo (na primer objekt Error). Za razliko od običajne spremenljivke identifikator, povezan s stavkom catch, obstaja samo v telesu bloka catch.

Sledi bolj realističen primer konstrukta poskusi/ulovi. Pokliče metodo factorial(), definirano v prejšnjem primeru, in metodi prompt() in alert() JavaScript na strani odjemalca za organiziranje vnosa in izhoda:

Poskusi ( // Vprašaj uporabnika za številko var n = Number(prompt("Enter a positive number", "")); // Izračunaj faktorial števila ob predpostavki // da je vnos veljaven var f = factorial( n); // Natisni rezultat alert(n + "! = " + f); ) catch (ex) ( // Če podatki niso pravilni, bo nadzor prenesen sem alert(ex); // Obvesti uporabnika o napaka)

Če uporabnik vnese negativno število, se prikaže opozorilo:

To je primer konstrukta try/catch brez stavka finally. Čeprav se finally ne uporablja tako pogosto kot catch, je kljub temu včasih uporaben. Izvedba bloka finally je zagotovljena, če je bil izveden vsaj del poskusnega bloka, ne glede na to, kako se je končala koda v poskusnem bloku. Ta funkcija se običajno uporablja za izvajanje končnih operacij po izvedbi kode v poskusnem nadaljevanju.

V običajni situaciji krmiljenje doseže konec poskusnega bloka in nato skoči na končni blok, ki izvede potrebne končne operacije. Če nadzor zapusti poskusni blok kot rezultat stavka return, continue ali break, se izvede blok finally, preden se nadzor prenese drugam.

Če pride do izjeme v poskusnem bloku in obstaja ustrezen blok catch za njeno obravnavo, se nadzor najprej prenese na blok catch in nato na blok finally. Če ni lokalnega bloka catch, potem nadzor najprej preide na blok finally in nato skoči na najbližji zunanji blok catch, ki lahko obravnava izjemo.

Če sam blok finally prenese nadzor z uporabo stavka return, continue, break ali throw ali s klicem metode, ki vrže izjemo, se čakajoči ukaz za prenos prekliče in izvede se nov. Na primer, če blok finally vrže izjemo, bo ta izjema nadomestila vsako predhodno vrženo izjemo.

Operater vrnitev prekine trenutno funkcijo in vrne njeno vrednost.

Izvorna koda za ta interaktivni primer je shranjena v repozitoriju GitHub. Če želite prispevati k projektu interaktivnih primerov, prosimo, klonirajte https://github.com/mdn/interactive-examples

Sintaksa

vrni [[izraz]]; izraz Izraz, katerega vrednost bo vrnjena. Če ni podano, je namesto tega vrnjeno undefined.

Opis

Ko je v funkciji poklican stavek return, se njegovo izvajanje ustavi. Podana vrednost se vrne na mesto, kjer je bila funkcija poklicana. Naslednja funkcija na primer vrne kvadratno vrednost svojega argumenta x (kjer je x število):

funkcija square(x) ( return x * x; ) var demo = square(3); // demo vrednost bo 9

Če vrnjena vrednost ni navedena, se namesto tega vrne undefined.

Naslednji izrazi vedno prekinejo izvajanje funkcije:

vrnitev; vrni resnico; vrni false; vrni x; vrnitev x + y / 3;

Samodejna podpičja

funkcija magic(x) (vrni funkcijo calc(x) (vrni x * 42); ) var answer = magic(); odgovor(1337); // 56154

Specifikacije

Specifikacija Stanje Komentar
ECMAScript 1. izdaja (ECMA-262) Standardno izvirna definicija
ECMAScript 5.1 (ECMA-262)
Standardno
ECMAScript 2015 (6. izdaja, ECMA-262)
Opredelitev "Izjave o vračilu" v tej specifikaciji.
Standardno
Najnovejši osnutek ECMAScript (ECMA-262)
Opredelitev "Izjave o vračilu" v tej specifikaciji.
Osnutek

Združljivost brskalnika

Tabela združljivosti na tej strani je ustvarjena iz strukturiranih podatkov. Če želite prispevati k podatkom, jih preverite v repozitoriju https://github.com/mdn/browser-compat-data in nam pošljite zahtevo za vlečenje za vaše spremembe.

Posodobite podatke o združljivosti na GitHub

RačunalnikiMobilnistrežnik
ChromerobFirefoxinternet ExplorerOperasafariandroid spletni pogledChrome za AndroidFirefox za AndroidOpera za AndroidSafari v sistemu iOSSamsung InternetNode.js
vrnitevChrome Popolna podpora 1 rob Popolna podpora 12 Firefox Popolna podpora 1 IE Popolna podpora 3 Opera Popolna podpora jasafari Popolna podpora jawebview android Popolna podpora 1 Chrome Android Popolna podpora 18 Firefox Android Popolna podpora 4 OperaAndroid Popolna podpora jaSafari iOS Popolna podpora jaSamsung Internet Android Popolna podpora 1.0 nodejs Popolna podpora ja

Funkcije so eden najpomembnejših gradnikov kode v JavaScriptu.

Funkcije so sestavljene iz nabora ukazov in običajno izvajajo eno določeno nalogo (na primer seštevanje števil, izračun korena itd.).

Koda, nameščena v funkciji, bo izvedena šele po eksplicitnem klicu te funkcije.

Deklaracija funkcije

1.Sintaksa:

//Deklaracija funkcije function FunctionName(var1, var2)( koda funkcije ) //Klic funkcije FunctionName(var1,var2);

2. Sintaksa:

//Deklaracija funkcije var functionname=function(var1, var2)(koda funkcije) //Klic funkcije functionname(var1,var2);

ime funkcije določa ime funkcije. Vsaka funkcija na strani mora imeti edinstveno ime. Navesti je treba ime funkcije z latinskimi črkami in se ne sme začeti s številkami.

per1 in per2 so spremenljivke ali vrednosti, ki jih je mogoče posredovati znotraj funkcije. Vsaki funkciji je mogoče posredovati neomejeno število spremenljivk.

Opomba: tudi če funkciji ni posredovana nobena spremenljivka, ne pozabite vstaviti oklepaja "()" za imenom funkcije.

Opomba: Imena funkcij v JavaScriptu razlikujejo med velikimi in malimi črkami.

Primer funkcije JavaScript

Funkcija messageWrite() v spodnjem primeru se bo izvedla šele po kliku gumba.

Opomba: ta primer uporablja dogodek onclick. Dogodki JavaScript bodo podrobno obravnavani pozneje v tej vadnici.



Posredovanje spremenljivk funkcijam

Funkcijam lahko posredujete neomejeno število spremenljivk.

Opomba: vse manipulacije s spremenljivkami znotraj funkcij se pravzaprav ne izvajajo na samih spremenljivkah, temveč na njihovi kopiji, zato se vsebina samih spremenljivk ne spremeni zaradi izvajanja funkcij.

/* Definirajte funkcijo, ki doda 10 posredovani spremenljivki in izpiše rezultat na stran */ function plus(a)( a=a+10; document.write("Izhod funkcije: " + a+"
"); ) var a=25; document.write("Vrednost spremenljivke pred klicem funkcije: "+a+"
"); // Pokliči funkcijo, ki ji posreduje spremenljivko a plus(a); document.write("Vrednost spremenljivke po klicu funkcije: "+a+"
");

Hiter pogled

Za dostop do globalne spremenljivke iz funkcije namesto njene kopije uporabite okno.ime_spremenljivke.

Funkcija plus(a)( window.a=a+10; ) var a=25; document.write("Vrednost spremenljivke pred klicem funkcije: "+a+"
"); plus(a); document.write("Vrednost spremenljivke po klicu funkcije: "+a+"
");

Hiter pogled

povratni ukaz

Z ukazom vrnitev Vrednosti lahko vrnete iz funkcij.



Hiter pogled

Vgrajene funkcije

Poleg uporabniško definiranih funkcij v JavaScript obstajajo tudi vgrajene funkcije.

Na primer vgrajena funkcija isFinite vam omogoča, da preverite, ali je posredovana vrednost veljavno število.

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90.33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("To je niz")+"
");

Hiter pogled

Opomba: celoten seznam vgrajene funkcije JavaScript, ki jih najdete v našem .

Lokalne in globalne spremenljivke

Spremenljivke, ustvarjene znotraj funkcij, se imenujejo lokalne spremenljivke. Do takih spremenljivk lahko dostopate samo znotraj funkcij, v katerih so bile definirane.

Po izvedbi funkcijske kode se takšne spremenljivke uničijo. To pomeni, da lahko spremenljivke z istim imenom definiramo v različnih funkcijah.

Spremenljivke, ki so ustvarjene zunaj funkcijske kode, se kličejo globalne spremenljivke do takšnih spremenljivk je mogoče dostopati od kjer koli v kodi.

Če deklarirate spremenljivko brez var znotraj funkcije, postane tudi globalna.

Globalne spremenljivke se uničijo le, ko je stran zaprta.



Hiter pogled

Opomba: ko je prikazana, bo var2 ničelna, ker func1 deluje na lokalni "različici" var2.

Uporaba anonimnih funkcij

Pokličejo se funkcije, ki ob deklaraciji ne vsebujejo imena anonimen.

Anonimne funkcije v bistvu niso deklarirane za njihov poznejši klic iz kode kot navadne funkcije, ampak za prehod na druge funkcije kot parameter.

Funkcija arrMap(arr,func)( var res=nova matrika; for (var i=0;i ");

Hiter pogled

Naredite sami

1. vaja. Popravite napake v spodnji kodi:

1. vaja

Popravite napako v kodi.



Naloga 2.

  1. Reproducirajte kodo funkcij 1-3 tako, da preučite njihovo vedenje pri podajanju različnih parametrov.
  2. Določite ključno besedo z interakcijo s funkcijo 4.

Naloga 2

//Pokliči prvo tajno funkcijo document.write(secfunc1(4,12) + "
"); // Klicanje druge tajne funkcije document.write(secfunc2(100,10) + "
"); //Pokliči tretjo tajno funkcijo secfunc3(23,10); document.write("
"); // Klicanje četrte tajne funkcije secfunc4("p");

Za uporabo sistema za komentiranje Disqus omogočite JavaScript.




Vrh