Funcții JavaScript. JavaScript expresiv: Funcții Funcționează ca valori

Oamenii cred că informatica este o artă pentru genii. În realitate, opusul este adevărat - doar o mulțime de oameni fac lucruri care stau unul peste altul, ca și cum ar fi alcătuit un zid de pietricele mici.

Donald Knuth

Ați văzut deja apeluri de funcții, cum ar fi alertă. Funcțiile sunt elementul de bază al programării JavaScript. Ideea de a împacheta o bucată dintr-un program și de a o numi ca variabilă este foarte populară. Este un instrument pentru structurarea programelor mari, reducerea repetiției, atribuirea de nume subrutinelor și izolarea subrutinelor unele de altele.

Cea mai evidentă utilizare a funcțiilor este crearea unui nou dicționar. A găsi cuvinte pentru proza ​​umană obișnuită este o formă proastă. Într-un limbaj de programare, acest lucru este necesar.

Vorbitorul mediu de limba rusă adult știe aproximativ 10.000 de cuvinte. Un limbaj de programare rar conține 10.000 de comenzi încorporate. Și vocabularul unui limbaj de programare este mai clar definit, deci este mai puțin flexibil decât unul uman. Prin urmare, de obicei trebuie să-i adăugăm propriile cuvinte pentru a evita repetarea inutilă.

Definiția funcției O definiție a funcției este o definiție de variabilă normală, unde valoarea pe care o primește variabila este o funcție. De exemplu, următorul cod definește un pătrat variabil care se referă la o funcție care calculează pătratul unui număr dat:

var pătrat = function(x) ( return x * x; ); console.log(pătrat(12)); // → 144

O funcție este creată de o expresie care începe cu cuvântul cheie function. Funcțiile au un set de parametri (în acest caz, doar x) și un corp care conține instrucțiunile care trebuie executate atunci când funcția este apelată. Corpul unei funcții este întotdeauna închis între acolade, chiar dacă constă dintr-o singură instrucțiune.

O funcție poate avea mai mulți parametri sau nici unul. În exemplul următor, makeNoise nu are o listă de parametri, în timp ce puterea are doi:

Var makeNoise = function() ( console.log("La naiba!"); ); a face zgomot(); // → La naiba! var putere = funcție (bază, exponent) (var rezultat = 1; pentru (var număr = 0; numărare)< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

Unele funcții returnează o valoare, cum ar fi puterea și pătratul, altele nu, cum ar fi makeNoise, care are doar un efect secundar. Instrucțiunea return definește valoarea returnată de funcție. Când procesarea programului ajunge la această instrucțiune, iese imediat din funcție și returnează această valoare în locul din codul de unde a fost apelată funcția. return fără o expresie returnează nedefinit .

Parametrii și domeniul de aplicare Parametrii unei funcții sunt la fel ca variabilele, dar valorile lor inițiale sunt setate atunci când funcția este apelată, nu în codul acesteia.

O proprietate importantă a funcțiilor este aceea că variabilele create în cadrul unei funcții (inclusiv parametrii) sunt locale în cadrul acelei funcții. Aceasta înseamnă că în exemplul de putere, rezultatul variabil va fi creat de fiecare dată când funcția este apelată, iar aceste încarnări separate ale acesteia nu sunt legate între ele în niciun fel.

Această localitate a variabilelor se aplică numai parametrilor și variabilelor create în interiorul funcțiilor. Variabilele stabilite în afara oricărei funcții sunt numite variabile globale deoarece sunt vizibile în întreg programul. De asemenea, puteți accesa astfel de variabile în cadrul unei funcții, cu excepția cazului în care ați declarat o variabilă locală cu același nume.

Următorul cod ilustrează acest lucru. Acesta definește și apelează două funcții care atribuie o valoare lui x. Prima o declară locală, schimbând astfel doar variabila locală. Al doilea nu declară, așa că lucrul cu x în interiorul funcției se referă la variabila globală x care a fost setată la începutul exemplului.

var x = „în afară”; var f1 = function() ( var x = "in interiorul f1"; ); f1(); jurnalul consolei(x); // → exterior var f2 = function() ( x = "inside f2"; ); f2(); jurnalul consolei(x); // → în interiorul f2

Acest comportament ajută la prevenirea interacțiunii accidentale între funcții. Dacă toate variabilele ar fi folosite oriunde în program, ar fi foarte dificil să vă asigurați că o variabilă nu este utilizată în scopuri diferite. Și dacă ar fi să refolosești o variabilă, te-ai confrunta cu efecte ciudate în care codul terță parte se încurcă cu valorile variabilei tale. Tratând variabilele locale-funcție astfel încât acestea să existe numai în cadrul funcției, limbajul face posibilă lucrul cu funcții ca și cum ar fi mici universuri separate, ceea ce vă permite să nu vă faceți griji pentru întregul cod în ansamblu.

Domenii imbricate JavaScript distinge mai mult decât variabilele globale și locale. Funcțiile pot fi definite în cadrul funcțiilor, rezultând mai multe niveluri de localitate.

De exemplu, următoarea funcție destul de lipsită de sens conține încă două în interior:

var landscape = function() ( var rezultat = ""; 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()); // → ___/""""\______/"\_

Funcțiile plat și munte văd variabila rezultat deoarece sunt în interiorul funcției în care este definită. Dar ei nu pot vedea variabilele de numărare ale celuilalt, deoarece variabilele unei funcții sunt în afara domeniului de aplicare a celeilalte. Și mediul din afara funcției de peisaj nu vede niciuna dintre variabilele definite în interiorul acestei funcții.

Pe scurt, în fiecare domeniu local, puteți vedea toate domeniile care îl conțin. Setul de variabile disponibile în interiorul unei funcții este determinat de locul în care această funcție este declarată în program. Toate variabilele din blocurile din jurul definiției funcției sunt vizibile - inclusiv cele definite pe nivel superiorîn programul principal. Această abordare a domeniilor este numită lexicală.

Oamenii care au studiat alte limbaje de programare ar putea crede că orice bloc închis între acolade își creează propriul mediu local. Dar în JavaScript, numai funcțiile creează domeniul de aplicare. Puteți utiliza blocuri de sine stătătoare:

var ceva = 1; ( var ceva = 2; // Faceți ceva cu variabila ceva... ) // Ieșire din bloc...

Dar ceva din interiorul blocului este aceeași variabilă ca și din exterior. Deși astfel de blocuri sunt permise, are sens să le folosești doar pentru instrucțiuni și bucle if.

Dacă acest lucru ți se pare ciudat, așa se pare nu numai ție. JavaScript 1.7 a introdus cuvântul cheie let, care funcționează ca var, dar creează variabile care sunt locale pentru orice bloc dat, nu doar pentru funcție.

Funcții ca valori Numele de funcții sunt de obicei folosite ca nume pentru o parte dintr-un program. O astfel de variabilă este setată odată și nu se modifică. Deci, este ușor să confundați o funcție cu numele ei.

Dar acestea sunt două lucruri diferite. Un apel de funcție poate fi folosit ca o variabilă simplă - de exemplu, ele pot fi folosite în orice expresie. Este posibil să stocați un apel de funcție într-o nouă variabilă, să îl transmiteți ca parametru unei alte funcții și așa mai departe. De asemenea, variabila care stochează apelul funcției rămâne o variabilă obișnuită și valoarea acesteia poate fi modificată:

Var launchMissiles = function(value) ( ​​​​missileSystem. launch("te rog!"); ); if (safeMode) launchMissiles = function(value) (/* release */);

În capitolul 5, vom discuta lucrurile minunate care pot fi făcute prin trecerea apelurilor de funcții către alte funcții.

Declararea funcțiilor Există o versiune mai scurtă a expresiei „var pătrat = funcție…”. Cuvântul cheie function poate fi folosit la începutul unei instrucțiuni:

funcția pătrat(x) ( return x * x; )

Aceasta este o declarație de funcție. Instrucțiunea definește pătratul variabil și îi atribuie funcția dată. Pana acum totul este ok. Există o singură capcană într-o astfel de definiție.

Console.log("Viitorul spune:", viitor()); function future() ( returnează „ÎNcă nu avem mașini zburătoare.”; )

Acest cod funcționează chiar dacă funcția este declarată sub codul care o folosește. Acest lucru se datorează faptului că declarațiile de funcții nu fac parte din execuția normală de sus în jos a programelor. Ei „se mută” în partea de sus a domeniului lor de aplicare și pot fi apelați de orice cod din acel domeniu. Acest lucru este uneori convenabil, deoarece puteți scrie codul în ordinea cea mai logică, fără a vă face griji că trebuie să definiți toate funcțiile de mai sus unde sunt utilizate.

Dar ce se întâmplă dacă plasăm o declarație de funcție în interiorul unui bloc sau al unei bucle condiționate? Nu trebuie să faci asta. Din punct de vedere istoric, diferite platforme pentru rularea JavaScript au tratat astfel de cazuri în mod diferit, iar standardul actual al limbajului interzice acest lucru. Dacă doriți ca programele dvs. să ruleze în mod consecvent, utilizați declarațiile de funcție numai în cadrul altor funcții sau al programului principal.

Exemplu de funcție() (funcția a() () // Normule if (ceva) (funcția b() () // Ay-yy-yy! ) )

Stiva de apeluri Este util să privim cum funcționează ordinul de execuție cu funcțiile. Aici program simplu cu apeluri de funcții multiple:

Funcția greet(who) ( console.log("Salut, " + who); ) greet("Semyon"); console.log ("Pokeda");

Este procesat cam așa: apelarea greet face ca trecerea să sară la începutul funcției. Apelează funcția încorporată console.log, care preia controlul, își face treaba și returnează controlul. Apoi ajunge la sfârșitul salutului și se întoarce la locul din care a fost chemat. Următoarea linie apelează din nou console.log.

Schematic, aceasta poate fi prezentată după cum urmează:

top greet console.log salut top console.log top

Deoarece funcția trebuie să revină de unde a fost apelată, computerul trebuie să-și amintească contextul din care a fost apelată funcția. Într-un caz, console.log ar trebui să se schimbe înapoi la salut. În altul, se întoarce la sfârșitul programului.

Locul în care computerul își amintește contextul se numește stivă. De fiecare dată când funcția este apelată, contextul curent este împins deasupra stivei. Când funcția revine, scoate contextul de sus din stivă și îl folosește pentru a continua.

Stocarea stivă necesită spațiu de memorie. Când stiva devine prea mare, computerul se oprește din execuție și emite ceva de genul „depășire a stivei” sau „prea multă recursivitate”. Următorul cod demonstrează acest lucru - pune computerului o întrebare foarte complexă care duce la salturi nesfârșite între două funcții. Mai exact, ar fi sărituri infinite dacă computerul ar avea o stivă infinită. În realitate, stiva se debordează.

Funcție chicken() ( return egg(); ) function egg() ( return chicken(); ) console. log(chicken() + "a venit primul."); // → ??

Argumente opționale Următorul cod este perfect legal și rulează fără probleme:

Alertă(„Bună ziua”, „Bună seara”, „Salut tuturor!”);

Oficial, funcția are un singur argument. Cu toate acestea, atunci când este provocată astfel, ea nu se plânge. Ignoră restul argumentelor și arată „Bună ziua”.

JavaScript este foarte indulgent cu privire la numărul de argumente transmise unei funcții. Dacă treci prea mult, cei în plus vor fi ignorați. Prea puține - celor care lipsesc li se va atribui valoarea nedefinită.

Dezavantajul acestei abordări este că este posibil - și chiar probabil - să treci funcției un număr greșit de argumente și nimeni nu îți va plânge acest lucru.

Avantajul este că puteți crea funcții care iau argumente opționale. De exemplu, în următoarea versiune a funcției de putere, aceasta poate fi apelată atât cu doi, cât și cu un singur argument - în acest din urmă caz, exponentul va fi egal cu doi, iar funcția funcționează ca un pătrat.

Puterea funcției (bază, exponent) ( dacă (exponent == nedefinit) exponent = 2; rezultat var = 1; pentru (număr var = 0; numărare< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

În capitolul următor, vom vedea cum corpul unei funcții vă poate spune numărul exact de argumente transmise acesteia. Acest lucru este util pentru că vă permite să creați o funcție care acceptă orice număr de argumente. De exemplu, console.log folosește această proprietate și tipărește toate argumentele transmise acestuia:

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

Închideri Capacitatea de a folosi apelurile de funcții ca variabile, cuplată cu faptul că variabilele locale sunt re-create de fiecare dată când o funcție este apelată, ne aduce la un punct interesant. Ce se întâmplă cu variabilele locale când o funcție eșuează?

Următorul exemplu ilustrează această problemă. Acesta declară funcția wrapValue, care creează o variabilă locală. Apoi returnează o funcție care citește acea variabilă locală și returnează valoarea acesteia.

Funcția wrapValue(n) ( var localVariable = n; return function() ( return localVariable; ); ) var wrap1 = wrapValue(1); var wrap2 = wrapValue(2); jurnalul consolei(wrap1()); // → 1 console.log(wrap2()); // → 2

Acesta este valid și funcționează așa cum ar trebui - rămâne accesul la variabilă. Mai mult decât atât, mai multe instanțe ale aceleiași variabile pot exista în același timp, confirmând și mai mult faptul că variabilele locale sunt recreate cu fiecare apel de funcție.

Această capacitate de a lucra cu o referință la o anumită instanță a unei variabile locale se numește închidere. O funcție care închide variabilele locale se numește funcție de închidere. Nu numai că vă eliberează de îngrijorarea cu privire la duratele de viață variabile, dar vă permite și să utilizați funcțiile în mod creativ.

Cu o ușoară modificare, transformăm exemplul nostru într-o funcție care înmulțește numerele cu orice număr dat.

Funcție multiplicator(factor) ( return function(number) ( return number * factor; ); ) var de două ori = multiplicator(2); console.log(de două ori(5)); // → 10

O variabilă separată precum localVariable din exemplul wrapValue nu mai este necesară. Deoarece parametrul este el însuși o variabilă locală.

Este nevoie de practică pentru a începe să gândești așa. O versiune bună a modelului mental este să ne imaginăm că funcția îngheață codul în corpul său și îl învelește într-un pachet. Când vedeți funcția return(...) (...), gândiți-vă la ea ca la un panou de control pentru o bucată de cod înghețată pentru a fi folosită mai târziu.

În exemplul nostru, multiplicatorul returnează o bucată de cod înghețată pe care o stocăm în variabila de două ori. Ultima linie apelează funcția conținută în variabilă, care activează codul salvat (număr returnat * factor;). Încă are acces la variabila factor care a fost definită când a fost apelat multiplicatorul și, de asemenea, are acces la argumentul transmis în timpul dezghețarii (5) ca parametru numeric.

Recursie O funcție se poate autodenomina dacă are grijă să nu depășească stiva. O astfel de funcție se numește recursivă. Iată un exemplu de implementare alternativă a exponențiației:

Funcția putere(bază, exponent) ( if (exponent == 0) returnează 1; else returnează bază * putere(bază, exponent - 1); ) console.log(putere(2, 3)); // → 8

Acesta este modul în care matematicienii definesc exponentiația și poate că aceasta descrie conceptul mai elegant decât un ciclu. Funcția se autoapelează de multe ori cu argumente diferite pentru a obține înmulțirea multiplă.

Cu toate acestea, această implementare are o problemă - într-un mediu JavaScript normal, este de 10 ori mai lentă decât versiunea cu buclă. Buclă este mai ieftină decât apelarea unei funcții.

Dilema viteză versus eleganță este destul de interesantă. Există un anumit decalaj între confortul uman și confortul mașinii. Orice program poate fi accelerat făcându-l mai mare și mai complicat. Programatorul trebuie să găsească echilibrul potrivit.

În cazul primei exponențieri, bucla inelegantă este destul de simplă și directă. Nu are sens să-l înlocuiești cu recursivitate. Deseori, totuși, programele funcționează cu concepte atât de complexe încât se dorește reducerea eficienței prin creșterea lizibilității.

Regula de bază, care s-a repetat de multe ori și cu care sunt complet de acord - nu vă faceți griji cu privire la performanță până nu sunteți sigur că programul încetinește. Dacă da, găsește acolo piesele care durează cel mai mult și schimbă eleganța cu eficiență.

Desigur, nu ar trebui să ignorăm complet performanța imediat. În multe cazuri, la fel ca în cazul exponențiației, nu obținem multă simplitate din soluțiile elegante. Uneori, un programator experimentat vede imediat că o abordare simplă nu va fi niciodată suficient de rapidă.

Aduc în discuție acest lucru pentru că prea mulți programatori începători se agață de eficiență chiar și în lucruri mici. Rezultatul este mai mare, mai complex și adesea nu lipsit de erori. Scrierea acestor programe durează mai mult și adesea funcționează nu mult mai repede.

Dar recursiunea nu este întotdeauna doar o alternativă mai puțin eficientă la bucle. Unele probleme sunt mai ușor de rezolvat prin recursivitate. Cel mai adesea, aceasta este o traversare a mai multor ramuri de copac, fiecare dintre ele se poate ramifica.

Iată o ghicitoare pentru tine: poți obține un număr infinit de numere, începând cu numărul 1 și apoi fie adunând 5, fie înmulțind cu 3. Cum scriem o funcție care, dat fiind un număr, încearcă să găsească o succesiune de astfel de numere. adunări și înmulțiri care duc la un număr dat? De exemplu, numărul 13 poate fi obținut prin înmulțirea întâi a 1 cu 3 și apoi adunând 5 de două ori. Și numărul 15 este în general imposibil de obținut așa.

Solutie recursiva:

Funcția findSolution(țintă) (funcția find(start, history) ( if (start == target) return history; else if (start > target) return null; else return find(start + 5, "(" + history + " + 5)") || find(start * 3, "(" + history + " * 3)"); ) return find(1, "1"); ) console.log(findSolution(24)); // → (((1 * 3) + 5) * 3)

Acest exemplu nu găsește neapărat cea mai scurtă soluție - o satisface pe oricare. Nu mă aștept să înțelegeți imediat cum funcționează programul. Dar să ajungem la fundul acestui mare exercițiu de gândire recursivă.

Funcția internă find este recursivă. Este nevoie de două argumente - numărul curent și un șir care conține o înregistrare a modului în care am ajuns la acel număr. Și returnează fie un șir care arată secvența noastră de pași, fie null.

Pentru a face acest lucru, funcția efectuează una dintre cele trei acțiuni. Dacă numărul dat este egal cu obiectivul, atunci istoricul curent este doar modalitatea de a-l atinge, motiv pentru care este returnat. Dacă numărul dat este mai mare decât ținta, nu are rost să continui înmulțirea și adunarea, deoarece în acest fel va crește doar. Și dacă nu am atins încă obiectivul, funcția încearcă ambele căi posibile pornind de la numărul dat. Ea se invocă de două ori, o dată cu fiecare dintre modalități. Dacă primul apel nu revine nul, se întoarce. În caz contrar, al doilea este returnat.

Pentru a înțelege mai bine modul în care funcția obține efectul dorit, să ne uităm la apelurile sale care apar în căutarea unei soluții pentru numărul 13.

Găsiți(1, "1") găsiți(6, "(1 + 5)") găsiți(11, "((1 + 5) + 5)") găsiți(16, "(((1 + 5) + 5 ) + 5)") găsire prea mare(33, "(((1 + 5) + 5) * 3)") găsire prea mare(18, "((1 + 5) * 3)") găsire prea mare( 3, "(1 * 3)") găsiți(8, "((1 * 3) + 5)") găsiți(13, "(((1 * 3) + 5) + 5)") găsit!

Indentația arată adâncimea stivei de apeluri. Prima dată, funcția de căutare se autoapelează de două ori pentru a verifica soluțiile începând cu (1 + 5) și (1 * 3). Primul apel caută o soluție care începe cu (1 + 5) și folosește recursiunea pentru a verifica toate soluțiile care dau un număr mai mic sau egal cu numărul dorit. Nu îl găsește și returnează null. Apoi operatorul || și trece la un apel de funcție care examinează opțiunea (1 * 3). Aici suntem norocoși, pentru că în al treilea apel recursiv obținem 13. Acest apel returnează un șir, iar fiecare dintre || trece acest șir deasupra pe parcurs, returnând soluția ca rezultat.

Creșterea funcțiilor Există două moduri mai mult sau mai puțin naturale de a introduce funcții într-un program.

În primul rând, scrieți cod similar de mai multe ori. Acest lucru ar trebui evitat - mai mult cod înseamnă mai mult spațiu pentru erori și mai mult material de lectură pentru cei care încearcă să înțeleagă programul. Deci luăm funcționalitatea recurentă, îi dăm un nume bun și o punem într-o funcție.

A doua modalitate este că descoperiți necesitatea unei noi funcționalități care merită să fie plasate într-o funcție separată. Începeți cu numele funcției, apoi scrieți corpul acesteia. Puteți chiar să începeți prin a scrie codul care utilizează funcția înainte ca funcția în sine să fie definită.

Cât de dificil vă este să denumiți o funcție arată cât de bine înțelegeți funcționalitatea acesteia. Să luăm un exemplu. Trebuie să scriem un program care imprimă două numere, numărul de vaci și găini de la fermă, urmat de cuvintele „vaci” și „pui”. Trebuie să adăugați zerouri la numerele din față, astfel încât fiecare să ocupe exact trei poziții.

007 Vaci 011 Găini

Evident, avem nevoie de o funcție cu două argumente. Să începem să codificăm.
// funcția printFarmInventory printFarmInventory(vaci, găini) ( var cowString = String(vaci); 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);

Dacă adăugăm .length unui șir, obținem lungimea acestuia. Se pare că buclele while adaugă zerouri de început la numere până când obțin un șir de 3 caractere.

Gata! Dar de îndată ce suntem pe cale să trimitem codul fermierului (împreună cu un control serios, desigur), el sună și ne spune că are porci la fermă și am putea adăuga rezultatul numărului de porci la program?

Desigur că este posibil. Dar când începem să copiem și să lipim codul din aceste patru linii, ne dăm seama că trebuie să ne oprim și să ne gândim. Trebuie să existe o cale mai bună. Încercăm să îmbunătățim programul:

// funcția de ieșireZeroPaddedWithLabel printZeroPaddedWithLabel(număr, etichetă) ( 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);

Lucrări! Dar numele printZeroPaddedWithLabel este puțin ciudat. Combină trei lucruri - output, zero padding și o etichetă - într-o singură funcție. În loc să încărcăm întregul fragment care se repetă într-o funcție, să evidențiem un concept:

// adăugați funcția Zeros zeroPad(număr, lățime) ( var șir = șir(număr); while (șir.lungime)< 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);

O funcție cu un nume frumos și descriptiv zeroPad face codul mai ușor de înțeles. Și poate fi folosit în multe situații, nu numai în cazul nostru. De exemplu, pentru a afișa tabele formatate cu numere.

Cât de inteligente și de versatile ar trebui să fie funcțiile? Putem scrie o funcție simplă care completează un număr cu zerouri până la trei poziții, precum și o funcție de uz general fantezist pentru formatarea numerelor care acceptă fracții, numere negative, alinierea punctelor, completarea cu caractere diferite și așa mai departe.

O regulă bună este să adăugați doar funcționalitatea de care aveți cu siguranță nevoie. Uneori este tentant să creezi cadre de uz general pentru fiecare mică nevoie. Rezistă-i. Nu vei termina niciodată treaba, ci doar scrie o grămadă de cod pe care nimeni nu le va folosi.

Funcții și efecte secundare Funcțiile pot fi împărțite aproximativ în cele care sunt chemate pentru efectele lor secundare și cele care sunt chemate pentru a obține o anumită valoare. Desigur, este și posibil să combinați aceste proprietăți într-o singură funcție.

Prima funcție de ajutor din exemplul fermei, printZeroPaddedWithLabel, este apelată din cauza efectului secundar al tipăririi unui șir. Al doilea, zeroPad, din cauza valorii returnate. Și nu întâmplător a doua caracteristică este utilă mai des decât prima. Funcțiile care returnează valori sunt mai ușor de combinat între ele decât funcțiile care creează efecte secundare.

O funcție pură este un tip special de funcție de returnare a valorii care nu numai că nu are efecte secundare, dar nici nu depinde de efectele secundare ale restului codului - de exemplu, nu funcționează cu variabile globale care pot fi modificate accidental altundeva. O funcție pură, atunci când este apelată cu aceleași argumente, returnează același rezultat (și nu face nimic altceva) - ceea ce este destul de frumos. Este ușor să lucrezi cu ea. Apelul unei astfel de funcții poate fi înlocuit mental de rezultatul muncii sale, fără a schimba sensul codului. Când doriți să testați o astfel de funcție, puteți pur și simplu să o apelați și să vă asigurați că, dacă funcționează în acest context, va funcționa în oricare. Funcțiile nu atât de pure pot returna rezultate diferite în funcție de mulți factori și au efecte secundare greu de testat și de luat în considerare.

Cu toate acestea, nu ar trebui să fie timid să scrieți funcții care nu sunt destul de curate sau să începeți o curățare sacră a codului de astfel de funcții. Efectele secundare sunt adesea utile. Nu există nicio modalitate de a scrie o versiune pură a funcției console.log, iar această funcție este destul de utilă. Unele operații sunt mai ușor de exprimat folosind efecte secundare.

Rezumat Acest capitol v-a arătat cum să vă scrieți propriile funcții. Când cuvântul cheie function este folosit ca expresie, returnează un pointer la apelul funcției. Când este folosită ca instrucțiune, puteți declara o variabilă prin alocarea unui apel de funcție.

Cheia pentru înțelegerea funcțiilor este domeniile locale. Parametrii și variabilele declarate în interiorul unei funcții sunt locali pentru aceasta, recreați de fiecare dată când este apelată și nu sunt vizibile din exterior. Funcțiile declarate în interiorul unei alte funcții au acces la domeniul acesteia.

Este foarte util să împărțiți diferitele sarcini efectuate de program în funcții. Nu trebuie să vă repetați, funcțiile fac codul mai ușor de citit prin separarea lui în părți semantice, în același mod în care capitolele și secțiunile unei cărți ajută la organizarea textului simplu.

ExercisesMinimum În capitolul anterior a fost menționată funcția Math.min, care returnează cel mai mic dintre argumentele sale. Acum putem scrie noi înșine o astfel de funcție. Scrie functia min A care ia două argumente și returnează cel mai mic dintre ele.

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

Recursie Am văzut că operatorul % (restul) poate fi folosit pentru a determina dacă un număr (% 2) este par. Iată o altă modalitate de a determina:

Zero este egal.
Unitatea este ciudată.
Orice număr N are aceeași paritate ca N-2.

Scrieți o funcție recursivă isEven conform acestor reguli. Trebuie să ia un număr și să returneze o valoare booleană.

Testați-l pe 50 și 75. Încercați să-i dați -1. De ce se comportă așa? Este posibil să o reparăm cumva?

Testați-l pe 50 și 75. Vezi cum se comportă pe -1. De ce? Poti tu te gândești la o modalitate de a remedia asta?

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

Numărăm fasolea.

Numărul caracterului N al unui șir poate fi obținut prin adăugarea lui .charAt(N)(„string”.charAt(5)), similar cu obținerea lungimii unui șir cu .length. Valoarea returnată va fi un singur șir de caractere (de exemplu, „k”). Primul caracter al șirului are poziția 0, ceea ce înseamnă că ultimul personaj poziția va fi șir.lungime - 1. Cu alte cuvinte, un șir de două caractere va avea lungimea 2, iar pozițiile lui vor fi 0 și 1.

Scrieți o funcție countBs care ia un șir ca argument și returnează numărul de caractere „B” din șir.

Apoi scrieți o funcție countChar care funcționează un pic ca countBs, cu excepția faptului că necesită un al doilea parametru, caracterul pe care îl vom căuta în șir (în loc să numărăm doar numărul de caractere „B”). Pentru a face acest lucru, rescrieți funcția countBs.

Declarații de salt și gestionarea excepțiilor

O altă categorie de operatori de limbaj JavaScript sunt operatorii de salt. După cum sugerează și numele, aceste instrucțiuni fac ca interpretul JavaScript să sară într-o locație diferită din codul programului. Instrucțiunea break face ca interpretul să sară la sfârșitul unei bucle sau al altei instrucțiuni. Instrucțiunea continue face ca interpretul să sară peste restul corpului buclei, să sară înapoi la începutul buclei și să înceapă o nouă iterație. JavaScript are capacitatea de a eticheta instrucțiunile cu nume, astfel încât instrucțiunile break și continue pot fi specificate în mod explicit cărei bucle sau alte instrucțiuni îi aparțin.

Instrucțiunea return face ca interpretul să sară de la funcția apelată înapoi la punctul în care a fost apelată și să returneze valoarea apelului. Declarația throw ridică o excepție și este proiectată să funcționeze împreună cu instrucțiunile try/catch/finally care definesc un bloc de cod pentru a gestiona excepția. Acesta este un tip destul de complicat de instrucțiuni de salt: atunci când apare o excepție, interpretul sare la cel mai apropiat handler de excepție, care poate fi în aceeași funcție sau mai mare, pe stiva de returnare a funcției apelate.

Fiecare dintre acești operatori de salt este descris mai detaliat în următoarele subsecțiuni.

Etichete de instrucțiuni

Orice declarație poate fi marcată cu un identificator și două puncte înaintea acesteia:

identificator: instrucțiune

Când etichetați o instrucțiune, îi dați un nume care poate fi apoi folosit ca referință oriunde în program. Puteți marca orice instrucțiune, dar are sens doar să marcați instrucțiunile care au un corp, cum ar fi bucle și instrucțiuni condiționale.

Dând un nume buclei, acesta poate fi apoi folosit în instrucțiuni break și continue, în interiorul buclei pentru a ieși din ea sau pentru a sări la începutul buclei, la următoarea iterație. Declarațiile break și continue sunt singurele instrucțiuni din limbajul JavaScript care pot conține etichete – acestea sunt discutate mai detaliat mai târziu. Următorul este un exemplu de instrucțiune while cu o etichetă și o instrucțiune continue folosind acea etichetă:

Mainloop: while (token != null) ( // Codul programului a fost omis... continuă mainloop; // Treceți la următoarea iterație a buclei numite )

Identificatorul folosit ca etichetă de declarație poate fi orice identificator JavaScript valid, cu excepția unui cuvânt rezervat. Numele etichetelor sunt separate de numele variabilelor și ale funcțiilor, așa că puteți utiliza identificatori care se potrivesc cu numele de variabile sau funcții ca etichete.

Etichetele de instrucțiuni sunt definite numai în cadrul instrucțiunilor cărora li se aplică (și, desigur, în cadrul instrucțiunilor imbricate în ele). Instrucțiunile imbricate nu pot fi etichetate cu aceiași identificatori ca și instrucțiunile care le conțin, dar două instrucțiuni independente pot fi etichetate cu aceeași etichetă. Instrucțiunile etichetate pot fi reetichetate. Adică, orice instrucțiune poate avea mai multe etichete.

declarație de pauză

Instrucțiunea break face ca instrucțiunea cea mai interioară buclă sau switch să iasă imediat. Am văzut deja exemple de utilizare a unei instrucțiuni break în interiorul unei instrucțiuni switch mai devreme. În bucle, este de obicei folosit pentru a ieși imediat din buclă atunci când, dintr-un motiv oarecare, este necesar să se încheie execuția buclei.

Când ciclul este foarte stare complexă de finalizare, este adesea mai ușor să implementați aceste condiții cu o instrucțiune break decât să încercați să le exprimați într-o singură buclă condiționată. Următorul exemplu încearcă să găsească un element de matrice cu o anumită valoare. Bucla se termină în mod obișnuit când se ajunge la sfârșitul matricei, sau cu instrucțiunea break, de îndată ce este găsită valoarea dorită:

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

În JavaScript, puteți specifica numele etichetei după cuvântul cheie break (un identificator fără două puncte):

break label_name;

Când instrucțiunea break este utilizată cu o etichetă, aceasta sare la sfârșitul instrucțiunii numite sau își încheie execuția. În absența unei instrucțiuni cu eticheta specificată, o încercare de a utiliza această formă a instrucțiunii break generează o eroare de sintaxă. O instrucțiune numită nu trebuie să fie o buclă sau o instrucțiune switch. Declarația break etichetată poate „scăpa” din orice instrucțiune care o conține. O declarație de anexare poate fi chiar un simplu bloc de declarații închise între acolade cu singurul scop de a o marca.

Nu poate fi introdus un caracter de linie nouă între cuvântul cheie break și numele etichetei. Acest lucru se datorează faptului că interpretul JavaScript inserează automat punct și virgulă lipsă: dacă rupeți o linie de cod între cuvântul cheie break și eticheta care îl urmează, interpretul va presupune că v-ați referit la forma simplă a acestui operator fără etichetă și va adăuga un punct și virgulă. .

Instrucțiunea break etichetată este necesară numai atunci când doriți să întrerupeți execuția unei instrucțiuni care nu este cea mai apropiată buclă de încadrare sau instrucțiunea switch.

continua declarația

Instrucțiunea continue este similară cu instrucțiunea break. Cu toate acestea, în loc să iasă din buclă, instrucțiunea continue începe o nouă iterație a buclei. Sintaxa pentru instrucțiunea continue este la fel de simplă ca și sintaxa pentru instrucțiunea break. Instrucțiunea continue poate fi folosită și cu o etichetă.

Instrucțiunea continue, indiferent dacă este neetichetată sau etichetată, poate fi utilizată numai în corpul unei bucle. Folosind-o oriunde altundeva duce la o eroare de sintaxă. Când este executată o instrucțiune continue, iterația curentă a buclei este întreruptă și începe următoarea. Pentru tipuri diferite ciclurile înseamnă lucruri diferite:

    În bucla while, expresia specificată la începutul buclei este verificată din nou, iar dacă este adevărată, corpul buclei este executat de la început.

    Bucla do/while sare la sfârșitul buclei, unde condiția este verificată din nou înainte ca bucla să se repete.

    În bucla for, expresia de increment este evaluată și expresia de test este evaluată din nou pentru a determina dacă următoarea iterație trebuie efectuată.

    Într-o buclă for/in, bucla începe din nou, atribuind variabilei specificate numele următoarei proprietăți.

Observați diferența în comportamentul instrucțiunii continue în buclele while și for. Bucla while revine direct la condiția sa, în timp ce bucla for evaluează mai întâi expresia de increment și apoi revine la condiție. Următorul exemplu arată utilizarea unei instrucțiuni continue neetichetate pentru a ieși din iterația curentă a unei bucle pentru numere pare:

var sum = 0; // Calculați suma numerelor impare de la 0 la 10 pentru (var i = 0; i

Instrucțiunea continue, precum break, poate fi folosită în bucle imbricate într-o formă care include o etichetă, caz în care bucla repornită nu este neapărat cea care conține imediat instrucțiunea continue. De asemenea, ca și în cazul pauzei, liniile noi între cuvântul cheie continue și numele etichetei nu sunt permise.

declarație de returnare

Un apel de funcție este o expresie și, ca toate expresiile, are o valoare. Declarația return din interiorul funcțiilor este utilizată pentru a determina valoarea returnată de funcție. Declarația return poate fi plasată numai în corpul unei funcții. Prezența sa oriunde altundeva este o eroare de sintaxă. Când se execută o instrucțiune return, funcția returnează valoarea expresiei programului apelant. De exemplu:

Dacă o funcție nu are o instrucțiune return, atunci când este apelată, interpretul va executa instrucțiunile din corpul funcției unul câte unul până ajunge la sfârșitul funcției, iar apoi va returna controlul programului care a apelat-o. În acest caz, expresia de apel va reveni nedefinită. Declarația de returnare este adesea ultima instructieîntr-o funcție, dar acest lucru este complet opțional: funcția va returna controlul programului apelant de îndată ce se ajunge la instrucțiunea return, chiar dacă este urmată de alte instrucțiuni în corpul funcției.

Instrucțiunea return poate fi folosită și fără expresie, caz în care pur și simplu anulează funcția și returnează nedefinit apelantului. De exemplu:

Funcția myFun(arr) ( // Dacă tabloul conține numere negative, anulați funcția pentru (var i = 0; i

declarație aruncă

O excepție este un semnal care indică faptul că a avut loc o excepție sau o eroare. Ridicarea unei excepții (aruncare) este o modalitate de a semnala o astfel de eroare sau excepție. A prinde o excepție (prinde) înseamnă a o gestiona, adică. luați măsurile necesare sau adecvate pentru a vă recupera din excepție.

În JavaScript, excepții sunt aruncate atunci când apare o eroare de rulare și când programul o ridică în mod explicit cu instrucțiunea throw. Excepțiile sunt capturate folosind instrucțiunile try/catch/finally, care sunt descrise mai târziu.

Instrucțiunea throw are următoarea sintaxă:

arunca expresie;

Rezultatul unei expresii poate fi o valoare de orice tip. Instrucțiunii throw i se poate transmite un număr reprezentând codul de eroare sau un șir care conține textul mesajului de eroare. Interpretul JavaScript aruncă excepții folosind o instanță a clasei Error a uneia dintre subclasele sale și puteți utiliza o abordare similară. Obiectul Error are o proprietate Nume, care definește tipul de eroare și proprietatea mesaj A care conține șirul transmis funcției de constructor. Următorul este un exemplu de funcție care ridică un obiect Error atunci când este apelată cu un argument nevalid:

// Funcția factorială a unui număr funcție factorial(număr) ( // Dacă argumentul de intrare nu este o valoare validă, // se aruncă o excepție! dacă (număr 1; i *= număr, număr--); /* gol corpul buclei */ return i ; ) console.log("5! = ", factorial(5)); console.log("-3! = ", factorial(-3));

Când se aruncă o excepție, interpretul JavaScript anulează imediat execuția normală a programului și sare la cel mai apropiat handler de excepții. Manipulatorii de excepții folosesc instrucțiunea catch a constructului try/catch/finally, care este descrisă în secțiunea următoare.

Dacă blocul de cod în care a apărut excepția nu are un construct catch corespunzător, interpretul analizează următorul bloc exterior de cod și verifică dacă un handler de excepție este asociat cu acesta. Aceasta continuă până când este găsit handler-ul.

Dacă o excepție este aruncată într-o funcție care nu conține o construcție try/catch/finally pentru a o gestiona, atunci excepția se propagă în codul care a numit funcția. Acesta este modul în care excepțiile se propagă prin structura lexicală a metodelor JavaScript în stiva de apeluri. Dacă un handler de excepție nu este găsit niciodată, excepția este tratată ca o eroare și raportată utilizatorului.

încercați/prindeți/în final construiți

Construcția try/catch/finally implementează mecanismul de gestionare a excepțiilor JavaScript. Instrucțiunea try din acest construct definește pur și simplu un bloc de cod în care sunt gestionate excepțiile. Blocul try este urmat de o instrucțiune catch cu un bloc de instrucțiuni de apelat dacă apare o excepție oriunde în blocul try. Declarația catch este urmată de un bloc final care conține cod care efectuează operațiunile finale care este garantat să ruleze indiferent de ceea ce se întâmplă în blocul try.

Atât blocul catch, cât și blocul final sunt opționale, dar cel puțin unul dintre ele trebuie să fie prezent după blocul de încercare. încercați, prindeți și în cele din urmă blocurile încep și se termină acolade. Aceasta este o parte obligatorie a sintaxei și nu poate fi omisă chiar dacă există o singură declarație între ele.

Următorul fragment ilustrează sintaxa și scopul construcției try/catch/finally:

Încercați ( // În mod normal, acest cod va rula fără probleme de la început până la sfârșit. // Dar, la un moment dat, poate arunca o excepție, // fie direct cu instrucțiunea throw, fie indirect, // apelând metoda care aruncă excepție. ) catch (ex) ( // Instrucțiunile din acest bloc sunt executate dacă și numai dacă apare o excepție în blocul try //. Aceste instrucțiuni pot folosi o variabilă locală ex care // se referă la obiectul Error sau la altul valoare specificată în instrucțiunea throw. // Acest bloc poate fie să gestioneze excepția într-un fel, fie // să o ignore și să facă altceva, fie // să arunce din nou excepția cu o instrucțiune throw. ) în cele din urmă ( // Acest bloc conține instrucțiuni care sunt întotdeauna executate, indiferent dacă , // ce s-a întâmplat în blocul try Se execută dacă blocul try s-a încheiat: // 1) ca de obicei, ajungând la sfârșitul blocului // 2) din cauza ruperii, continuă sau instrucțiuni return // 3) cu excepția tratată așa cum este indicată în blocul catch de mai sus // ​​4) cu o excepție neprinsă care continuă să // se propagă la niveluri superioare)

Rețineți că cuvântul cheie catch este urmat de un identificator între paranteze. Acest identificator este similar cu un parametru de funcție. Când o excepție este capturată, acest parametru va fi setat la o excepție (de exemplu, un obiect Error). Spre deosebire de o variabilă normală, identificatorul asociat unei instrucțiuni catch există doar în corpul blocului catch.

Următorul este un exemplu mai realist de construcție try/catch. Apelează metoda factorial() definită în exemplul anterior și metodele prompt() și alert() ale JavaScript-ului la nivelul clientului pentru a organiza intrarea și ieșirea:

Try ( // Cere utilizatorului un număr var n = Number(prompt("Introduceți un număr pozitiv", "")); // Calculați factorialul unui număr, presupunând // intrarea este validă var f = factorial( n); // Tipăriți alerta de rezultat(n + "! = " + f); ) catch (ex) ( // Dacă datele sunt incorecte, controlul va fi transferat aici alert(ex); // Notificați utilizatorul despre eroarea )

Dacă utilizatorul introduce un număr negativ, va fi afișat un mesaj de avertizare:

Acesta este un exemplu de construcție try/catch fără o declarație finally. Deși în final nu este folosit la fel de des ca captura, este totuși util uneori. Blocul final este garantat să se execute dacă cel puțin o parte din blocul try a fost executată, indiferent de modul în care s-a încheiat codul din blocul try. Această caracteristică este de obicei folosită pentru a efectua operațiuni finale după ce codul a fost executat într-o continuare a încercării.

Într-o situație normală, controlul ajunge la sfârșitul blocului de încercare și apoi sare la blocul final, care efectuează operațiunile finale necesare. Dacă controlul iese dintr-un bloc try ca urmare a unei instrucțiuni return, continue sau break, blocul final este executat înainte ca controlul să fie transferat în altă parte.

Dacă apare o excepție într-un bloc try și există un bloc catch adecvat pentru a o gestiona, controlul este mai întâi transferat blocului catch și apoi blocului final. Dacă nu există un bloc de captură local, atunci controlul trece mai întâi la blocul final și apoi sare la cel mai apropiat bloc de captură exterior care poate gestiona excepția.

Dacă blocul final în sine transferă controlul prin utilizarea unei instrucțiuni return, continue, break sau throw sau apelând o metodă care aruncă o excepție, comanda de transfer în așteptare este anulată și se execută una nouă. De exemplu, dacă blocul final lansează o excepție, acea excepție va înlocui orice excepție lansată anterior.

Instrucțiunea return încheie execuția funcției curente și returnează valoarea acesteia.

Codul sursă pentru acest exemplu interactiv este stocat într-un depozit GitHub. Dacă doriți să contribui la proiectul de exemple interactive, clonează https://github.com/mdn/interactive-examples

Sintaxă returnează [[expresie]]; expresie Expresia a cărei valoare va fi returnată. Dacă nu este specificat, undefined este returnat. Descriere

Când o instrucțiune return este apelată într-o funcție, execuția acesteia se oprește. Valoarea specificată este returnată la locul în care a fost apelată funcția. De exemplu, următoarea funcție returnează valoarea pătrată a argumentului său, x (unde x este un număr):

function square(x) ( return x * x; ) var demo = square(3); // valoarea demo va fi 9

Dacă nu este specificată nicio valoare de returnare, undefined este returnat.

Următoarele expresii termină întotdeauna execuția unei funcții:

întoarcere; returnează adevărat; returnează fals; întoarce x; întoarce x + y / 3;

Funcția punct și virgulă automată magic(x) ( return function calc(x) ( return x * 42 ); ) var răspuns = magic(); răspuns (1337); // 56154 Specificații Comentariu privind starea specificației
ECMAScript prima ediție (ECMA-262) Standard definiție originală
ECMAScript 5.1 (ECMA-262)
Standard
ECMAScript 2015 (ediția a 6-a, ECMA-262)
Definiția „Declarație de returnare” în această specificație.
Standard
Ultima versiune ECMAScript (ECMA-262)
Definiția „Declarație de returnare” în această specificație.
Proiect
Compatibilitate browser

Tabelul de compatibilitate de pe această pagină este generat din date structurate. Dacă doriți să contribuiți la date, verificați-l din https://github.com/mdn/browser-compat-data depozit și trimiteți-ne o cerere de extragere pentru modificările dvs.

Actualizați datele de compatibilitate pe GitHub

Computere Mobile Server Chrome Edge Firefox Internet Explorer Opera Safari Vizualizare web Android Chrome pentru Android Firefox pentru Android Opera pentru Android Safari pe iOS Samsung Internet Node.jsîntoarcere
Crom Suport complet 1 Suport complet Edge 12Asistență completă Firefox 1Suport complet IE 3Suport complet Opera DaSuport complet Safari DaWebView Android Suport complet 1Asistență completă Chrome Android 18Firefox Android Suport complet 4Opera Android Suport complet DaSafari iOS Suport complet DaSamsung Internet Android Suport complet 1.0nodejs Suport complet Da

Funcțiile sunt unul dintre cele mai importante blocuri de cod în JavaScript.

Funcțiile constau dintr-un set de comenzi și îndeplinesc de obicei o sarcină specifică (de exemplu, însumarea numerelor, calcularea unei rădăcini etc.).

Codul plasat într-o funcție va fi executat numai după apelul explicit la acea funcție.

Declarație de funcție

1. Sintaxă:

//Funcția de declarare a funcției FunctionName(var1, var2)( Codul funcției) //Apelul funcției FunctionName(var1,var2);

2. Sintaxă:

//Declarația funcției var functionname=function(var1, var2)(Function code) //Function call functionname(var1,var2);

functionname specifica numele functiei. Fiecare funcție de pe pagină trebuie să aibă un nume unic. Trebuie dat numele funcției cu litere latineși nu trebuie să înceapă cu cifre.

var1 și var2 sunt variabile sau valori care pot fi transmise în interiorul unei funcții. Un număr nelimitat de variabile poate fi transmis fiecărei funcție.

Vă rugăm să rețineți: chiar dacă nu sunt transmise variabile funcției, nu uitați să introduceți paranteze „()” după numele funcției.

Rețineți că numele funcțiilor din JavaScript sunt sensibile la majuscule și minuscule.

Exemplu de funcție JavaScript

Funcția messageWrite() din exemplul de mai jos va fi executată numai după ce se face clic pe butonul.

Rețineți că acest exemplu utilizează evenimentul onclick. Evenimentele JavaScript vor fi tratate în detaliu mai târziu în acest tutorial.

// Funcția scrie text în funcția de pagină messageWrite() ( document.write("Acest text a fost scris în pagină folosind JavaScript!"); )

Transmiterea de variabile la funcții

Puteți trece un număr nelimitat de variabile la funcții.

Vă rugăm să rețineți: toate manipulările asupra variabilelor din interiorul funcțiilor sunt de fapt efectuate nu asupra variabilelor în sine, ci asupra copiei acestora, astfel încât conținutul variabilelor în sine nu se modifică ca urmare a execuției funcțiilor.

/* Definiți o funcție care adaugă 10 la variabila transmisă și scoate rezultatul în pagină */ function plus(a)( a=a+10; document.write("Ieșire funcție: " + a+"
"); ) var a=25; document.write ("Valoare variabilă înainte de apelul funcției: "+a+"
"); // Apelați funcția trecându-i variabila a plus(a); document.write("Valoarea variabilei după apelarea funcției: "+a+"
");

Vizualizare rapidă

Pentru a accesa o variabilă globală dintr-o funcție, mai degrabă decât o copie a acesteia, utilizați window.variable_name .

Funcția plus(a)( fereastră.a=a+10; ) var a=25; document.write("Valoare variabilă înainte de apelul funcției: "+a+"
"); plus(a); document.write("Valoare variabilă după apelul funcției: "+a+"
");

Vizualizare rapidă

comanda returnare

Cu comanda return, puteți returna valori din funcții.

//Funcția sum returnează suma variabilelor transmise acesteia function sum(v1,v2)( return v1+v2; ) document.write("5+6=" + sum(5,6) + "
"); document.write("10+4=" + sum(10,4) + "
");

Vizualizare rapidă

Funcții încorporate

Pe lângă funcțiile definite de utilizator, JavaScript are și funcții încorporate.

De exemplu, funcția încorporată isFinite vă permite să verificați dacă valoarea transmisă este un număr valid.

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90.33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("Acesta este un șir")+"
");

Vizualizare rapidă

Notă: lista plina funcții JavaScript încorporate pe care le puteți găsi în .

Variabile locale și globale

Variabilele create în interiorul funcțiilor se numesc variabile locale. Puteți accesa astfel de variabile numai în cadrul funcțiilor în care au fost definite.

După executarea codului funcției, astfel de variabile sunt distruse. Aceasta înseamnă că variabilele cu același nume pot fi definite în funcții diferite.

Variabilele care sunt create în afara codului funcției sunt numite variabile globale; astfel de variabile pot fi accesate de oriunde în cod.

Dacă declarați o variabilă fără var în interiorul unei funcții, aceasta devine și globală.

Variabilele globale sunt distruse numai atunci când pagina este închisă.

//Declară variabilele globale var1 și var2 var var1="var1 există"; var var2; funcția func1() ( //Atribuiți o valoare lui var2 în interiorul funcției func1 var var2="var2 există"; ) //Trimite conținutul variabilei var1 și var2 dintr-o altă funcție în funcția de pagină func2() ( //Ieșire conținutul variabilei var1 document.write( var1 + "
"); //Afișează conținutul variabilei var2 document.write(var2); )

Vizualizare rapidă

Rețineți că var2 va fi gol atunci când este afișat, deoarece func1 funcționează pe „versiunea” locală a var2.

Utilizarea funcțiilor anonime

Funcțiile care nu conțin un nume atunci când sunt declarate sunt numite anonime.

Funcțiile anonime sunt declarate practic nu pentru apelarea lor ulterioară din cod ca funcții obișnuite, ci pentru trecerea la alte funcții ca parametru.

Funcția arrMap(arr,func)( var res=new Array; for (var i=0;i


Top