Si të konfiguroni telefonat inteligjentë dhe PC. Portali informativ

Javascript duke përdorur një funksion të deklaruar më parë në një tjetër. Funksione

Artikulli është në ndërtim e sipër!

Një artikull në të cilin do të shqyrtojmë se çfarë është një funksion, si dhe versionin tradicional (klasik) të punës me të. Përveç kësaj, ne do të analizojmë se cilat janë argumentet (parametrat) e funksionit dhe kthimit të operatorit.

Çfarë është një funksion?

Një funksion është disa grup udhëzimesh të cilit mund t'i jepet një emër dhe më pas referojuni atij me këtë emër nga kudo në program.

Një shembull klasik i përdorimit të një funksioni. Faqja e internetit ka kod JavaScript, ndonjë fragment në të cilin përsëritet disa herë... Për të shmangur këtë mundeni formësoni këtë fragment si funksion, a pastaj thirre atë në vendet e duhura në kod me emrin e këtij funksioni. Duke thirrur këtë funksion do të thotë duke ndjekur udhëzimet të vendosura në të.

Si mund të organizoj ekzekutimin e disa detyrave në JavaScript duke përdorur funksione? Për ta bërë këtë, ata zakonisht bëjnë këtë:

  • ndani detyrën në pjesët përbërëse të saj (nëndetyra);
  • nëndetyrat formalizohen përmes funksioneve;
  • zhvilloni kodin kryesor duke përdorur një thirrje për funksionet e gjeneruara.

Si rezultat, një program i tillë bëhet më i strukturuar. Është më e lehtë të bësh ndryshime të ndryshme dhe të shtosh veçori të reja në të.

Deklarata dhe thirrja e funksionit

Operacionet e funksionit në JavaScript mund të ndahen në 2 hapa:

  • deklaratë (krijim) funksione.
  • thirrje (ekzekutim) këtë funksion.

Deklarata e funksionit. Krijimi i një funksioni në JavaScript fillon duke shkruar fjalën kyçe të funksionit, e ndjekur nga emri i funksionit, pastaj në kllapa x, nëse është e nevojshme. janë renditur parametrat ndjekur nga udhëzimet që janë të mbyllura në mbajtëse kaçurrelë.

// Deklarata e funksionit someName Funksioni someName () (alarm ("Ju thirrët funksionin someName!");) JavaScript - Sintaksa e deklarimit të funksionit

Funksionet e këtij lloji në JavaScript quhen deklaratën e deklaratës së funksionit... Përveç këtij lloji, JavaScript dallon edhe funksionet shprehja e përkufizimit të funksionit dhe shprehja e funksionit me shigjetë.

Formimi i emrit të funksionit ndjek të njëjtat rregulla si emri i ndryshores. ato. mund të përmbajë shkronja, numra (0-9), shenja "$" dhe "_". Rekomandohet të përdorni vetëm shkronjat e alfabetit anglez (a-z, A-Z) si shkronja. Emri i funksionit, si dhe emri i ndryshores, nuk mund të fillojnë me një shifër.

Një funksion mund të ketë aq parametra sa të doni, ose aspak. Në çdo rast tregohen kllapat. Nëse ka disa parametra, atëherë ato duhet të ndahen midis tyre duke përdorur një presje. Parametrat e funksionit adresohen me emrin e tyre.

Komplet udhëzues, i mbyllur në kllapa kaçurrelë është kodi i funksionit që do të ekzekutohet kur të thirret.

Thirrja e funksionit. Funksioni i deklaruar nga e saja nuk do të ekzekutohet... Për ta nisur, duhet ta telefononi. Funksioni thirret duke specifikuar emrin dhe dy kllapa. Argumentet jepen brenda kllapave, nëse është e nevojshme.

// thirrni funksionin e dhënë në shembullin e mëparshëm someName (); JavaScript - Sintaksa e thirrjes së funksionit

A është një funksion në JavaScript një objekt?

Funksionet në JavaScript janë objekte. Në JavaScript, gjithçka është përgjithësisht një objekt, përveç gjashtë llojeve primitive të të dhënave. Dhe nëse funksioni është një objekt, atëherë një referencë për të mund të ruhet në një ndryshore.

// Deklarata e funksionit someName funksion someName () (alarm ("Ju thirrët funksionin someName!");) var referencë = someName;

Pas kësaj, mund ta telefononi funksionin si kjo:

Referenca ();

Parametrat dhe argumentet e funksionit

Argumentet e funksionit- këto janë vlerat që i kalohen funksionit në fazën e thirrjes së tij. Ndani argumentet nga njëri-tjetri me presje.

// thirrni funksionin sayWelcome me dy argumente të kaluara në të sayWelcome ("Ivan", "Ivanov"); // një thirrje tjetër në funksionin sayWelcome me dy argumente sayWelcome ("Peter", "Petrov");

Parametrat e funksionitËshtë një nga mënyrat në JavaScript që mund t'i referoheni argumenteve brenda një funksioni. Parametrat e funksionit në fazën e deklarimit të tij përshkruhen në kllapa.

Me fjale te tjera parametrat e funksionit- këto janë variabla lokale që krijohen automatikisht në fazën e fillimit të funksionit. Si vlera, parametrat marrin argumentet përkatëse që i kalohen funksionit në momentin e thirrjes së tij. Parametrat mund të aksesohen vetëm brenda këtij funksioni, jashtë tij nuk ekzistojnë.

// deklarimi i funksionit sayWelcome, i cili ka funksionin me dy parametra sayWelcome (userFirstName, userLastName) (// një udhëzim që shfaq vlerat e parametrave "userFirstName" dhe "userLastName" në konsolën e konsolës.log ("Welcome, " + emri i përdoruesit + "" + emri i përdoruesit );)

Në JavaScript, kur thirrni një funksion numri i argumenteve nuk duhet të jetë i njëjtë me numrin e parametrave... Parametrat që nuk janë caktuar në një vlerë kur thirren do të jenë të papërcaktuar.

Për shembull, le të thërrasim funksionin nga shembulli i mësipërm pa specifikuar një ose dy parametra:

// thirrni funksionin sayWelcome dhe kaloni një argument në të sayWelcome ("Peter"); // Mirësevini Peter të papërcaktuar // thirrni funksionin sayWelcome pa i kaluar atij argumente sayWelcome (); // Mirë se vini, i papërcaktuar i papërcaktuar

Një shembull i një funksioni që thjesht do të printojë argumentet që i kalohen atij në tastierën e shfletuesit:

// funksioni i deklarimit të funksionit outputParam (param1, param2, param3) (console.log (param1 + ";" + param2 + ";" + param3);) // thërret në funksionin outputParam me një numër të ndryshëm parametrash që i kalojnë atij outputParam ("Rain", "Borë", "Mjegull"); // Shi; borë; Dalja e mjegullësParam (17); // 17; i papërcaktuar; dalje e padefinuarParam (24.33); // 24; 33; dalje e papërcaktuarParam (); // e papërcaktuar; i papërcaktuar; të papërcaktuara

Një mënyrë tjetër për t'iu referuar argumenteve brenda një funksioni është përdorimi i objektit të argumenteve speciale. Argumentet aksesohen nëpërmjet argumenteve në të njëjtën mënyrë si elementët e një grupi të rregullt, d.m.th. me numrat e tyre serial. Kështu, argumenti është argumenti i parë, argumentet është i dyti, e kështu me radhë.

// Deklarata e funksionit shuma e funksionit sum (num1, num2) (/ * num1 ose argumente - merr vlerën e 1 argumentit num2 ose argumenteve - merr vlerën e argumentit 2 * / var sum1 = num1 + num2, sum2 = argumentet + argumentet; ktheni "Shuma, e marrë nga mënyra 1 është "+ shuma 1 +"; shuma e marrë nga mënyra 2 është e barabartë me "+ shuma2;) / * shtypni rezultatin e funksionit të shumës në tastierën 7 - argumenti i parë (mund t'i referoheni ai si me emrin num1 ashtu edhe duke përdorur argumente) 4 - argumenti i dytë (mund t'i referoheni si me emrin num2 ashtu edhe duke përdorur argumente) * / console.log (shuma (7,4));

Dallimi kryesor midis këtyre metodave është se e para prej tyre ju lejon të përdorni vetëm ato argumente që u emëruan në fazën e deklarimit të funksionit. Metoda e dytë ju lejon të merrni vlerën e çdo argumenti, edhe nëse ai nuk ka emër (me numër rendor). Kjo veçori e gjuhës JavaScript ju lejon të krijoni funksione fleksibël të gjithanshëm.

Përveç marrjes së argumenteve, objekti i argumenteve ju lejon gjithashtu të dini se sa argumente ka. Kjo bëhet duke përdorur veçorinë gjatësi.

Përsëriteni mbi argumentet kaluar në funksion, ju mund, për shembull, duke përdorur një për ose për ... të ciklit.

// Deklarata e funksionit shuma e funksionit sum () (var i = 0; console.log ("Dalja e të gjitha argumenteve duke përdorur një cikli for"); për (i; i< arguments.length; i++) { console.log(i + 1 + " аргумент равен " + arguments[i]); } console.log("Вывод всех аргументов с помощью цикла for...of"); for (arg of arguments) { console.log(arg); } } // вызов функции sum sum(7, 4, 3, 1);

Një funksion që printon në tastierë të gjitha argumentet e kaluara në të dhe numrin e tyre:

// Funksioni i deklarimit të funksionit myFunction () (var i; console.log ("Numri i parametrave të kaluar =" + argumentet.length); // përsërit mbi të gjithë parametrat duke përdorur ciklin for për (i = 0; i< arguments.length; i++) { console.log(i + " параметр = " + arguments[i]); } } // вызовы функции myFunction myFunction(3, 7, 27, "JavaScript"); myFunction(); myFunction("Яблоки", "Груши", "Апельсины");

Një funksion që shton të gjitha argumentet e kaluara në të (numri i tyre nuk dihet paraprakisht):

// Deklarimi i funksionit var myCalc = funksioni () (// përsëritet mbi të gjithë parametrat duke përdorur ciklin for var i, shuma = 0; për (i = 0; i lt; argumentet.gjatësia; i ++) (shuma + = argumentet [i] ;) // ktheni shumën si rezultat ktheni shumën;) // thirrni funksionin (dalja në tastierë) console.log (myCalc (4, 20, 17, -6));

Si rezultat, duke përdorur objektin e argumenteve, mund të zbatoni në trupin e funksionit:

  • kontrollimi i numrit të argumenteve të miratuara;
  • sa parametra përpunohen.

Përveç vetë funksionit, funksionet e tjera që janë në të gjithashtu kanë qasje në argumentet që i kalohen atij në fazën e thirrjes.

Funksioni mainF (p1, p2) (funksioni childF () (console.log ("p1 =" + p1 + "; p2 =" + p2);) childF ();) mainF (3, 5); // p1 = 3; p2 = 5 mainF (4, 7); // p1 = 4; p2 = 7

Vlera e parazgjedhur e parametrit

Që nga ECMAScript 2015 (6) parametri i funksionit ju mund të vendosni vlerën që do të ketë si parazgjedhje.

Për shembull, le të vendosim parametrin "color" në vlerën e tij të paracaktuar të barabartë me "# 009688":

Funksioni setBGColor (ngjyra = "# 009688") (document.body.style.backgroundColor = ngjyra;) setBGColor (); // ngjyra e sfondit do të jetë # 009688 setBGColor ("e kuqe"); // ngjyra e sfondit do të jetë e kuqe

Përpara ECMAScript 2015, mund të vendosni një parametër në një vlerë të paracaktuar, për shembull, ishte kështu:

Funksioni setBGColor (ngjyrë) (ngjyra = ngjyra! == e papërcaktuar? Ngjyra: "# 009688"; // vendosni ngjyrën e paracaktuar në "# 009688" document.body.style.backgroundColor = ngjyra;)

Parametrat e pushimit

Nëse, kur thërrisni një funksion, i kaloni më shumë argumente sesa ka parametra, atëherë mund të merrni pjesën tjetër duke përdorur të ashtuquajturat patametrat e pushimit... Kjo veçori është shfaqur në gjuhë që nga ECMAScript 2015.

// ... nums janë parametrat e mbetur, të cilët mund të aksesohen në këtë rast me emrin nums funksion doMath (mathAction, ... nums) (var rezultat = 0; nums.forEach (funksioni (vlera) (ndërprerës (mathAction ) ( rasti "shuma": rezultat + = vlera; thyerje; rasti "sumCube": rezultat + = vlera ** 3; pushim; rasti "shuma katror": rezultat + = vlera ** 2; thyerje; i padëgjuar: rezultat = 0; )) ) kthe rezultatin;) console.log (doMath ("shuma", 3, 4, 21, -4)); // 24 (3 + 4 + 21 + (-4)) console.log (doMath ("sumSquare", 1, 4)); // 17 (1 ^ 2 + 4 ^ 2) console.log (doMath ("sumCube", 3, 2, 4)); // 99 (3 ^ 3 + 2 ^ 3 + 4 ^ 3)

Deklarata e kthimit

Deklarata e kthimit synon të kthejë vlerën ose rezultatin e vlerësimit të shprehjes së funksionit aktual. Vlera ose shprehja duhet të ndahet nga kthimi me një hapësirë. Përveç kësaj, deklarata e kthimit përfundon ekzekutimin e funksionit, d.m.th. të gjitha udhëzimet pas tij nuk do të ekzekutohen.

Një funksion JavaScript kthen gjithmonë një rezultat, pavarësisht nëse deklarata e kthimit përdoret apo jo.

// funksioni që kthen funksionin e rezultatit sayWelcome (userFirstName, userLastName) (nëse ((! userFirstName) || (! userLastName)) kthen "Mirë se erdhe, përdorues anonim"; përndryshe kthe "Mirë se erdhe," + userLastEmri + "" + userFirstName ; ) // deklarata e ndryshores person var person; // cakto rezultatin e funksionit sayWelcome to the person variable person = sayWelcome ("Ivan", "Ivanov"); // printoni vlerën e ndryshores në konsolën e konsolës.log (person); // Një udhëzim që do të printojë në konsolë rezultatin e funksionit sayWelcome console.log (sayWelcome ("Peter", "Petrov")); // Një udhëzim që do të printojë në konsolë rezultatin e funksionit sayWelcome console.log (sayWelcome ("Sidorov")); JavaScript - Funksioni me vlefshmërinë e parametrave

Një funksion JavaScript, si rezultat i ekzekutimit të tij, gjithmonë kthen një rezultat, edhe nëse ai nuk është i përcaktuar qartë duke përdorur deklaratën e kthimit. Ky rezultat është i papërcaktuar.

// 1. një funksion që nuk kthen asnjë funksion rezultati sayWelcome (userFirstName, userLastName) (console.log ("Welcome," + userLastName + "" + userFirstName);) // përpiquni të merrni rezultatin nga një funksion që bën mos ktheni asgjë konsol .log (thoniMirë se erdhe ("Ivan", "Ivanov")); ( ditë) ;) // përpiquni të merrni rezultatin nga një funksion që përmban një deklaratë kthimi pa një vlerë konsol.log (sayDay ("21 shkurt 2016")); JavaScript - Merrni një vlerë nga një funksion që nuk kthen asgjë

I njëjti rezultat do të merret nëse nuk specifikoni një vlerë kthimi për deklaratën e kthimit.

Mbingarkimi i funksionit në JavaScript

Mbingarkimi i funksionit në programim është aftësia për të deklaruar funksione të shumta me të njëjtin emër në të njëjtin shtrirje. Funksione të tilla ndryshojnë nga njëri-tjetri në llojin dhe numrin e argumenteve. Secili funksion ka logjikën e vet të programit. Mbingarkimi i funksionit përdoret në mënyrë që veprime të ngjashme të mund të kryhen duke përdorur një emër të vetëm funksioni.

JavaScript nuk mbështet mbingarkimin e funksionit siç është, për shembull, në gjuhët e ngjashme me C-në. ato. JavaScript nuk mund të krijojë funksione të shumta me të njëjtin emër në të njëjtën fushë.

Funksionalitet i ngjashëm mund të zbatohet në JavaScript duke përdorur hapat e mëposhtëm:

  • Për të kontrolluar nëse një argument është miratuar apo jo, përdorni një kusht me kontrollimin e vlerës së tij për të papërcaktuar.
  • Përdorni vetinë e gjatësisë së objektit për të kontrolluar numrin e argumenteve të kaluara në një funksion.
  • Përdorni operatorët typeof ose instanceof për të gjetur llojin e vlerës së argumentit të kaluar.
  • Për të punuar me një numër të ndryshueshëm argumentesh, përdorni objektin e argumenteve.
  • Duke filluar në ECMAScript6, mund të jepni vlerat e paracaktuara për argumentet.

Për shembull, le të krijojmë një funksion që mund të thirret me një ose dy argumente:

// deklarimi i një funksioni që ndryshon ngjyrën e sfondit të elementeve funksioni setBgColor (bgColor, elemente) (// nëse parametri i elementeve nuk specifikohet kur thirret if (elementet === të papërcaktuara) (// atëherë barazoni vlerën e tij "div" elementet = "div ";) // merrni të gjithë elementët elementë = $ (elemente); // përsëritni mbi të gjithë elementët dhe vendosini ato në elementët e specifikuar të ngjyrës së sfondit.secili (funksioni () ($ (this) .css (" sfond -color ", bgColor) ;));) / * Thirrni funksionin setBgColor me një parametër. Sepse Parametri 2 nuk është specifikuar, atëherë ky funksion do të ndryshojë ngjyrën e sfondit të të gjithë elementëve div. * / SetBgColor ("jeshile"); / * Thirrni funksionin setBgColor me 2 parametra. Sepse 2 parametër është specifikuar, atëherë ky funksion do të ndryshojë ngjyrën e sfondit vetëm të elementeve të butonit * / SetBgColor ("# ff0000", "button");

Le të bëjmë disa ndryshime në kodin e mësipërm. Gjegjësisht, le të specifikojmë vlerën e paracaktuar për parametrin e dytë:

// deklarimi i një funksioni që ndryshon ngjyrën e sfondit të elementeve // ​​parametri i elementeve është vendosur në "div" sipas funksionit të paracaktuar setBgColor (bgColor, elementet = "div") (// merrni të gjithë elementët e elementeve = $ (elemente); / / përsëritni mbi të gjithë elementët dhe vendosini ato në elementët e specifikuar të ngjyrës së sfondit.secili (funksioni () ($ (ky) .css ("ngjyra e sfondit", bgColor);));) // thirrni funksionin setBgColor, duke specifikuar një parametri setBgColor ("jeshile" ); // thirrni funksionin setBgColor, duke specifikuar 2 parametra setBgColor ("# ff0000", "button");

Një shembull se si në JavaScript mund të zbatoni një funksion "të mbingarkuar" që llogarit numrin e kalorive që i nevojiten një personi në ditë:

// funksioni i përshkrimit të funksionit countCal (gjinia, lartësia) (// parametrat: seksi (gjinia) dhe lartësia (lartësia) var rezultat; nëse ((seks === 0) || (seks === "burrë")) ( rezultat = (lartësia - 100) * 20;) tjetër nëse ((seks === 1) || (seks === "grua")) (rezultati = (lartësia - 105) * 19;) nëse (rezultati) ( // argumentet - niveli i aktivitetit nëse (argumentet) (rezultati * = argumentet;) console.log ("Numri i kcal për jetën normale:" + rezultati);) else (console.log ("Parametrat e pavlefshëm janë specifikuar");) ) / * thirrni një funksion dhe kaloni 2 argumente në të (1 është "man", mund të aksesohet duke përdorur emrin seksi dhe argumentet; 2 është vlera 185, mund të aksesohet duke përdorur emrin seksi dhe argumentet) * / countCal ("burrë", 185); / * thirrja e funksionit dhe kalimi i tij 3 parametra, megjithëse ka vetëm 2 në përshkrimin e funksionit (në këtë rast, mund të merrni vlerën e 3 parametrave vetëm si argumente) * / countCal (0, 185, 2);

Rekursioni

Rekursioni është një thirrje brenda trupit të një funksioni në vetvete.

Një thirrje funksioni zakonisht kryhet në varësi të mënyrës se si deklarohet me emër ose përmes një ndryshoreje që përmban një referencë për këtë funksion.

Funksioni fakt (n) (nëse (n === 1) (kthimi 1;) kthen faktin (n-1) * n;) konsol.log (fakt (5)); // 120

Ju mund ta thërrisni një funksion brenda trupit të tij jo vetëm me emër, por edhe duke përdorur vetinë e thirrësit të objektit të argumenteve. Por është më mirë të mos përdoret kjo pronë, sepse është e vjetëruar. Përveç kësaj, në mënyrë strikte, nuk funksionon fare.

Cilat janë funksionet e integruara (standarde)?

JavaScript ka një grup të madh funksionesh të integruara (standarde). Këto funksione janë përshkruar tashmë në vetë motorin e shfletuesit. Pothuajse të gjitha janë metoda të një objekti.

Për shembull, për të thirrur funksionin e integruar të alarmit (metodën), nuk ka nevojë të deklarohet paraprakisht. Është përshkruar tashmë në shfletuesin. Metoda e alarmit thirret duke specifikuar një emër, kllapa dhe një argument brenda tyre. Kjo metodë është krijuar për të shfaqur një mesazh në ekran në formën e një kutie dialogu. Mesazhi me tekst është marrë nga vlera e parametrit të këtij funksioni.

// thirrni alarmin e alarmit të funksionit ("Disa tekst"); JavaScript - Thirrja e funksionit të alarmit

Funksionet janë një koncept kyç në JavaScript. Tipari më i rëndësishëm i gjuhës është mbështetja e klasit të parë për funksionet. (funksionon si qytetar i klasit të parë)... Çdo një funksion është një objekt, dhe kështu mund të manipulohet si një objekt, në veçanti:

  • kalojnë si argument dhe kthehen si rezultat kur thirren funksione të tjera (funksione të rendit më të lartë);
  • krijoni në mënyrë anonime dhe caktoni vlera variablave ose vetive të objektit.

Kjo përcakton fuqinë e lartë shprehëse të JavaScript dhe na lejon ta klasifikojmë atë si një nga gjuhët që zbatojnë paradigmën e programimit funksional (e cila në vetvete është shumë e lezetshme për shumë arsye).

Funksioni JavaScript një lloj i veçantë objektesh që ju lejon të zyrtarizoni një logjikë të caktuar të sjelljes dhe përpunimit të të dhënave me anë të gjuhës.

Për të kuptuar se si funksionojnë funksionet, është e nevojshme (dhe a është e mjaftueshme?) të keni një ide për pikat e mëposhtme:

Deklarata e funksionit

Funksionet e formularit "deklarata e deklaratës së funksionit"

Deklarata e funksionit ( përcaktimi i funksionit, ose deklarata e funksionit, ose deklaratë funksioni) përbëhet nga fjala kyçe e funksionit dhe pjesët e mëposhtme:

  • Emri i funksionit.
  • Një listë e parametrave (të pranuar nga funksioni) të mbyllura në kllapa () dhe të ndara me presje.
  • Udhëzimet që do të ekzekutohen pas thirrjes së funksionit janë të mbyllura në kllapa kaçurrelë ().

Për shembull, kodi i mëposhtëm deklaron një funksion të thjeshtë të quajtur katror:

Funksioni katror (numri) (numri i kthimit * numri;)

Funksioni katror merr një parametër të quajtur numër. Përbëhet nga një instruksion, që do të thotë të ktheni parametrin e këtij funksioni (ky është numër) të shumëzuar në vetvete. Deklarata e kthimit tregon vlerën që do të kthehet nga funksioni.

Numri i kthimit * numri;

Parametrat primitivë (për shembull, një numër) i kalohen funksionit sipas vlerës; kuptimi i kalohet funksionit, por nëse funksioni ndryshon vlerën e parametrit, ky ndryshim nuk do të pasqyrohet globalisht ose pas një thirrjeje funksioni.

Nëse kaloni një objekt si parametër (jo primitiv, për shembull, ose objekte të përcaktuara nga përdoruesi), dhe funksioni ndryshon një veti të objektit të kaluar në të, ky ndryshim do të jetë i dukshëm edhe jashtë funksionit, siç tregohet në shembullin e mëposhtëm:

Funksioni myFunc (theObject) (theObject.make = "Toyota";) var mycar = (make: "Honda", model: "Accord", viti: 1998); var x, y; x = mycar.make; // x merr vlerën "Honda" myFunc (mycar); y = mycar.make; // y merr vlerën "Toyota" // (vetia u ndryshua nga funksioni)

Funksionet e formës "shprehje përkufizimi i funksionit"

Një funksion i sintaksës së "deklaratës së funksionit" është një deklaratë ( deklaratë), një funksion tjetër mund të jetë i formës "shprehje përkufizimi i funksionit". Një funksion i tillë mund të jetë anonim(ajo nuk ka emër). Për shembull, funksioni katror mund të quhet kështu:

Var katror = funksioni (numri) (numri i kthimit * numri;); var x = katror (4); // x merr vlerën 16

Megjithatë, një emër mund të caktohet për të thirrur veten brenda vetë funksionit dhe për korrigjuesin ( korrigjues) për të identifikuar një funksion në gjurmët e pirgut ( gjurmët e pirgut; "gjurmë" - "gjurmë" / "ngulitje").

Var faktorial = funksioni fac (n) (kthimi n< 2 ? 1: n * fac(n - 1); }; console.log(factorial(3));

Funksionet e formës "shprehje përkufizimi i funksionit" janë të dobishme kur një funksion kalohet si argument në një funksion tjetër. Shembulli i mëposhtëm tregon funksionin e hartës, i cili duhet të marrë funksionin si argument të parë dhe një grup si të dytën.

Harta e funksionit (f, a) (var rezultat =, // Krijo një grup të ri i; për (i = 0; i! = A.gjatësi; i ++) rezultati [i] = f (a [i]); rezultati i kthimit ;)

Në kodin e mëposhtëm, funksioni ynë merr një funksion, i cili është një shprehje për përcaktimin e funksionit, dhe e ekzekuton atë për çdo element të grupit të marrë si argument i dytë.

Harta e funksionit (f, a) (var rezultat =; // Krijo një grup të ri var i; // Deklaroni variablin për (i = 0; i! = A.gjatësi; i ++) rezultati [i] = f (a [i ]); kthen rezultatin;) var f = funksioni (x) (kthimi x * x * x;) numrat var =; var kubi = hartë (f, numra); konsol.log (kub);

Funksioni kthen:.

Në JavaScript, një funksion mund të deklarohet me kusht. Për shembull, funksioni i mëposhtëm do t'i caktohet variablit myFunc vetëm nëse num është 0:

Var myFunc; nëse (num === 0) (myFunc = funksioni (theObject) (theObject.make = "Toyota";))

Përveç deklaratave të funksioneve të përshkruara këtu, mund të përdorni gjithashtu konstruktorin e Funksionit për të krijuar funksione nga një varg në kohën e ekzekutimit ( koha e ekzekutimit), si.

Metodaështë një funksion që është një veti e një objekti. Mund të mësoni më shumë rreth objekteve dhe metodave duke ndjekur lidhjen: Puna me objekte.

Thirrjet e funksionit

Një deklaratë funksioni nuk e kryen atë. Një deklaratë funksioni thjesht emërton funksionin dhe specifikon se çfarë duhet bërë kur funksioni thirret. Thirrni funksioni në fakt kryen veprimet e specifikuara me parametrat e specifikuar. Për shembull, nëse përcaktoni një funksion katror, ​​mund ta quani kështu:

Sheshi (5);

Ky pohim thërret funksionin me argumentin 5. Funksioni thërret instruksionet e tij dhe kthen 25.

Funksionet mund të jenë në shtrirje kur ato janë përcaktuar tashmë, por funksionet e formës "deklarata e deklarimit të funksionit" mund të ngrihen ( ngritja - ngritjen), ashtu si në këtë shembull:

Console.log (katrori (5)); / * ... * / funksioni katror (n) (kthimi n * n;)

Fusha e funksionit është funksioni në të cilin është përcaktuar, ose i gjithë programi nëse deklarohet në një nivel më të lartë.

Shënim: Kjo funksionon vetëm kur deklarata e funksionit përdor sintaksën e mësipërme (d.m.th. funksioni funcName () ()). Kodi më poshtë nuk do të funksionojë. Kjo do të thotë që ngritja e një funksioni funksionon vetëm me një deklaratë funksioni dhe nuk funksionon me një shprehje funksioni.

Console.log (katror); // katrori ngrihet me vlerë të papërcaktuar. konsol.log (katrori (5)); // TypeGabim: katrori nuk është një funksion var katror = funksion (n) (kthim n * n;)

Argumentet e funksionit nuk kufizohen në vargje dhe numra. Ju mund të kaloni objekte të tëra në një funksion. Funksioni show_props () (i deklaruar në Working with Objects) është një shembull i një funksioni që merr objektet si argument.

Funksioni mund të thërrasë veten. Për shembull, këtu është një funksion për të llogaritur në mënyrë rekursive faktorialin:

Funksioni faktorial (n) (nëse ((n === 0) || (n === 1)) kthen 1; përndryshe kthim (n * faktorial (n - 1));)

Pastaj mund të llogaritni faktorialet nga një në pesë si kjo:

Var a, b, c, d, e; a = faktorial (1); // a merr vlerën 1 b = faktorial (2); // b merr vlerën 2 c = faktorial (3); // c merr vlerën 6 d = faktorial (4); // d merr vlerën 24 e = faktorial (5); // e merr vlerën 120

Ka mënyra të tjera për të thirrur funksionin. Ka raste të shpeshta kur funksionet duhet të thirren në mënyrë dinamike, ose duhet të ndryshohen numrat e argumentit të funksionit, ose duhet të thirret një funksion me lidhje me një kontekst specifik. Rezulton se vetë funksionet janë objekte, dhe ato objekte nga ana e tyre kanë metoda (shikoni objektin). Një prej tyre është një metodë që mund të përdoret për të arritur këtë qëllim.

Shtrirja e funksionit

(sfera e funksionit)

Variablat e deklaruar në një funksion nuk mund të jenë të aksesueshme askund jashtë këtij funksioni, prandaj variablat (të cilat nevojiten posaçërisht për funksionin) deklarohen vetëm në fushëveprimin e funksionit. Në këtë rast, funksioni ka akses në të gjitha variablat dhe funksionet e deklaruara brenda fushës së tij. Me fjalë të tjera, një funksion i deklaruar në shtrirjen globale ka akses në të gjitha variablat në shtrirjen globale. Një funksion i deklaruar brenda një funksioni tjetër ka gjithashtu akses në të gjitha variablat e funksionit të tij prind dhe variablat e tjera në të cilat ky funksion prind ka akses.

// Variablat e mëposhtëm deklarohen në shtrirjen globale var num1 = 20, num2 = 3, emri = "Chamahk"; // Ky funksion është deklaruar në funksionin e shtrirjes globale multiply () (kthim num1 * num2;) shumëzoj (); // do të kthejë 60 // Shembull i një funksioni të ndërlidhur getScore () (var num1 = 2, num2 = 3; funksioni add () (emri i kthimit + "scored" + (num1 + num2);) ktheje add (); ) getScore ( ); // do të kthehet "Çamahk shënoi 5"

Funksionet e shtrirjes dhe stivës

(raft funksioni)

Rekursioni

Funksioni mund të thërrasë veten. Ka tre mënyra për ta quajtur këtë:

  1. sipas emrit të funksionit
  2. nga një ndryshore që i referohet një funksioni

Për shembull, merrni parasysh funksionin e mëposhtëm:

Var foo = shiriti i funksionit () (// deklaratat shkojnë këtu);

Brenda funksionit ( funksioni i trupit) të gjitha thirrjet e mëposhtme janë ekuivalente:

  1. bar ()
  2. argumentet.callee ()
  3. foo ()

Një funksion që thërret veten quhet funksioni rekurziv (funksioni rekurziv). Rezulton se rekursioni është i ngjashëm me ciklin ( lak). Të dy thërrasin disa herë disa kode dhe të dyja kërkojnë një kusht (për të shmangur një lak të pafund, ose më mirë rekursion të pafund). Për shembull, cikli i mëposhtëm:

Var x = 0; ndërsa (x< 10) { // "x < 10" - это условие для цикла // do stuff x++; }

mund të ndryshohet në një funksion rekurziv dhe duke thirrur këtë funksion:

Cikli i funksionit (x) (nëse (x> = 10) // "x> = 10" është një kusht për përfundimin e ekzekutimit (njëlloj si "! (X< 10)") return; // делать что-то loop(x + 1); // рекурсионный вызов } loop(0);

Megjithatë, disa algoritme nuk mund të jenë unaza të thjeshta përsëritëse. Për shembull, marrja e të gjithë elementëve të një strukture peme (për shembull) është më e lehtë për t'u zbatuar duke përdorur rekursionin:

Funksioni walkTree (nyja) (nëse (nyja == null) // return; // bëj diçka me elementet për (var i = 0; i< node.childNodes.length; i++) { walkTree(node.childNodes[i]); } }

Krahasuar me funksionin e ciklit, çdo thirrje rekursive në vetvete bën shumë thirrje rekursive.

Është gjithashtu e mundur të shndërrohen disa algoritme rekurzive në jo-rekurzive, por shpesh logjika e tyre është shumë komplekse dhe kjo do të kërkojë përdorimin e një pirg ( rafte). Në fakt, rekursioni përdor stach: funksion stack.

Sjellja e stivës mund të shihet në shembullin e mëposhtëm:

Funksioni foo (i) (nëse (i< 0) return; console.log("begin: " + i); foo(i - 1); console.log("end: " + i); } foo(3); // Output: // begin: 3 // begin: 2 // begin: 1 // begin: 0 // end: 0 // end: 1 // end: 2 // end: 3

Funksionet e mbivendosura dhe mbylljet

Ju mund të futni një funksion brenda një tjetri. Funksioni i mbivendosur ( funksioni i mbivendosur;e brendshme) private ( private) dhe vendoset në një funksion tjetër ( e jashtme). Kjo është se si mbyllje (mbyllje). Mbyllja është një shprehje (zakonisht një funksion) që mund të ketë variabla të lira së bashku me një mjedis që lidh ato variabla (që "mbyllet" ( "afër") shprehje).

Meqenëse një funksion i mbivendosur është një mbyllje, kjo do të thotë që një funksion i mbivendosur mund të "trashëgojë" ( trashëgojnë) argumentet dhe variablat e funksionit në të cilin është futur. Me fjalë të tjera, funksioni i mbivendosur përmban shtrirjen e jashtme ( "e jashtme") funksione.

Përmblidhni:

  • Funksioni i mbivendosur ka akses në të gjitha udhëzimet në funksionin e jashtëm.
  • Funksioni i mbivendosur formon një mbyllje: ai mund të përdorë argumentet dhe variablat e funksionit të jashtëm, ndërsa funksioni i jashtëm nuk mund të përdorë argumentet dhe variablat e funksionit të mbivendosur.

Shembulli i mëposhtëm tregon një funksion të ndërthurur:

Funksioni addSquares (a, b) (funksioni katror (x) (kthimi x * x;) ktheje katrorin (a) + katrorin (b);) a = addSquares (2, 3); // kthen 13 b = addSquares (3, 4); // kthen 25 c = addSquares (4, 5); // kthen 41

Meqenëse funksioni i mbivendosur formon një mbyllje, mund të thërrisni funksionin e jashtëm dhe të jepni argumente si për funksionet e jashtme ashtu edhe për ato të brendshme.

Funksioni jashtë (x) (funksioni brenda (y) (kthimi x + y;) kthimi brenda;) fn_brenda = jashtë (3); // Mendo pak: më jep një funksion që // kaloj 3 rezultat = fn_inside (5); // kthen 8 rezultat1 = jashtë (3) (5); // kthen 8

Ruajtja e variablave

Vini re se si u ruajt vlera x kur u kthye brenda. Një mbyllje duhet të vazhdojë me argumente dhe variabla në të gjithë shtrirjen e tij. Meqenëse çdo thirrje ofron argumente potencialisht të ndryshme, krijohet një mbyllje e re për secilën thirrje të jashtme. Kujtesa mund të pastrohet vetëm kur brenda është kthyer tashmë dhe nuk është më e disponueshme.

Kjo nuk ndryshon nga ruajtja e lidhjeve në objekte të tjera, por shpesh është më pak e dukshme sepse lidhjet nuk vendosen drejtpërdrejt dhe nuk mund të shihen atje.

Funksione me shumë fole

Funksionet mund të injektohen disa herë, d.m.th. funksioni (A) ruan funksionin (B), i cili ruan funksionin (C). Të dy B dhe C formojnë mbyllje, kështu që B ka qasje në variablat dhe argumentet e A, dhe C ka të njëjtën qasje në B. Përveç kësaj, meqenëse C ka qasje në B, e cila ka të njëjtën qasje në A, C gjithashtu ka të njëjtën qasje në B. i njëjti do të arrijë A. Kështu cloures mund të ruajnë disa fusha në vetvete; ato ruajnë në mënyrë rekursive shtrirjen e funksioneve që e përmbajnë atë. Quhet lidhjen me zinxhirë (zinxhir - zinxhir; Pse është emërtuar "zinxhirimi" do të shpjegohet më vonë)

Merrni parasysh shembullin e mëposhtëm:

Funksioni A (x) (funksioni B (y) (funksioni C (z) (konsola.log (x + y + z);) C (3);) B (2);) A (1); // tastiera do të shfaqë 6 (1 + 2 + 3)

Në këtë shembull, C ka akses në y nga B dhe x nga A. Kjo ndodh sepse:

  1. Funksioni B formon një mbyllje që përfshin A, d.m.th. B ka akses në argumentet dhe variablat e funksionit A.
  2. Funksioni C formon një mbyllje që përfshin B.
  3. Meqenëse mbyllja e funksionit B përfshin A, atëherë mbyllja C përfshin gjithashtu A, C ka qasje në argumentet dhe variablat e të dy funksioneve B dhe A. Me fjalë të tjera, C lidhet zinxhir (zinxhir) përfshin funksionet B dhe A në atë rend.

Në rendin e kundërt, megjithatë, kjo nuk është e vërtetë. A nuk ka akses në variablat dhe argumentet e C, sepse A nuk ka një qasje të tillë në B. Kështu, C mbetet private vetëm për B.

Konfliktet e emrave

Kur dy argumente ose variabla në fushëveprimin e një mbylljeje kanë të njëjtin emër, kjo ndodh konflikti i emrit (konflikti i emrit). Më shumë mbivendosur ( më e brendshme) scope ka përparësi, kështu që shtrirja më e mbivendosur ka përparësi dhe anasjelltas. Ky është zinxhiri i fushëveprimit ( zinxhiri i shtrirjes). Lidhja e parë është shtrirja më e thellë, dhe anasjelltas. Merrni parasysh sa vijon:

Funksioni jashtë () (var x = 5; funksioni brenda (x) (kthimi x * 2;) kthimi brenda;) jashtë () (10); // kthen 20 në vend të 10

Një konflikt emri ndodhi në deklaratën e kthimit x * 2 midis parametrit x të funksionit të brendshëm dhe ndryshores x të funksionit të jashtëm. Zinxhiri i shtrirjes këtu do të jetë si ky: (brenda ==> jashtë ==> objekti global ( objekt global)). Prandaj, x i funksionit të brendshëm ka përparësi ndaj jashtme, dhe marrim 20 (= 10 * 2), jo 10 (= 5 * 2).

Mbylljet

(Mbylljet)

Mbyllja është një nga veçoritë kryesore të JavaScript. JavaScript lejon futjen e funksionit dhe i jep funksionit të mbivendosur akses të plotë në të gjitha variablat dhe funksionet e deklaruara brenda funksionit të jashtëm (dhe variablave dhe funksioneve të tjera në të cilat funksioni i jashtëm ka akses).

Megjithatë, funksioni i jashtëm nuk ka akses në variablat dhe funksionet e deklaruara në funksionin e brendshëm. Kjo siguron një lloj kapsulimi për variablat brenda funksionit të mbivendosur.

Gjithashtu, meqenëse funksioni i mbivendosur ka akses në shtrirjen e funksionit të jashtëm, variablat dhe funksionet e deklaruara në funksionin e jashtëm do të vazhdojnë të ekzistojnë edhe pas ekzekutimit të tij për funksionin e ndërlidhur, nëse qasja në to dhe në të ruhet (që do të thotë se variablat e deklaruara në funksionet e jashtme ruhen vetëm nëse i thërret funksioni i brendshëm).

Një mbyllje krijohet kur një funksion i ndërthurur bëhet disi i disponueshëm në një fushë të caktuar jashtë funksionit të jashtëm.

Var pet = funksioni (emri) (// Funksioni i jashtëm ka deklaruar variablin "emër" var getName = funksion () (emri i kthimit; // Funksioni i mbivendosur ka akses në "emrin" e funksionit të jashtëm) return getName; ( kafsha ime shtepiake (); // "Vivie" është kthyer, // sepse edhe pas ekzekutimit të funksionit të jashtëm // emri ruhet për funksionin e vendosur

Një shembull më kompleks është paraqitur më poshtë. Një objekt me metoda për manipulimin e një funksioni të mbivendosur nga një funksion i jashtëm mund të kthehet ( kthimi).

Var createPet = funksioni (emri) (var seksi; kthimi (emri i vendosur: funksioni (emri i ri) (emri = emri i ri;), emri i marrë: funksioni () (emri i kthimit;), getSex: funksioni () (seksi i kthimit;), setSex: funksioni (newSex) (nëse (lloji i newSex === "string" && (newSex.toLowerCase () === "mashkull" || newSex.toLowerCase () === "femër")) (seks = newSex;)) )) var pet = krijoPet ("Vivie"); pet.getEmri (); // Vivie pet.setName ("Oliver"); pet.setSeks ("mashkull"); pet.getSex (); // pet.getName mashkull (); // Oliver

Në kodin e mësipërm, ndryshorja e emrit të funksionit të jashtëm është e disponueshme për funksionin e ndërthurur dhe nuk ka asnjë mënyrë tjetër për t'iu qasur variablave të ndërthurur përveçse përmes funksionit të mbivendosur. Variablat e mbivendosur të një funksioni të mbivendosur janë depo të sigurta për argumente dhe variabla të jashtëm. Ato përmbajnë të dhëna "të vazhdueshme" dhe "të kapsuluara" për të punuar me funksionet e mbivendosur. Funksionet as që duhet t'i caktohen një ndryshoreje ose të kenë një emër.

Var getCode = (funksioni () (var apiCode = "0] Eal (eh & 2"; // Një kod që nuk duam që të huajt të jenë në gjendje ta modifikojnë ... funksionin e kthimit () (kthimi apiCode;);) ( )) ; getCode (); // Kthen apiCode

Megjithatë, ka një numër grackash që duhen marrë parasysh kur përdorni mbylljet. Nëse funksioni privat përcakton një variabël me të njëjtin emër si emri i ndryshores në shtrirjen e jashtme, nuk ka asnjë mënyrë për të referuar variablin në shtrirjen e jashtme përsëri.

Var createPet = funksioni (emri) (// Funksioni i jashtëm përcakton një variabël të quajtur "emri". Kthimi (setEmri: funksioni (emri) (// Funksioni i mbyllur gjithashtu përcakton një ndryshore të quajtur "emri". Emri = emri; // Si mund t'i qasemi "emrit" të përcaktuar nga funksioni i jashtëm?)))

Përdorimi i objektit të argumenteve

Argumentet objekt i një funksioni është një pseudo-varg. Brenda një funksioni, mund t'i referoheni argumenteve si ky:

Argumentet [i]

ku i është rendorja e argumentit, duke filluar nga 0. Argumenti i parë i kaluar në funksion quhet argumente. Dhe për të marrë numrin e të gjitha argumenteve - argumentet.gjatësia.

Me objektin e argumenteve, ju mund të thërrisni një funksion duke i kaluar më shumë argumente sesa keni deklaruar zyrtarisht për të pranuar. Kjo është shumë e dobishme nëse nuk e dini saktësisht se sa argumente duhet të marrë funksioni juaj. Mund të përdorni arguments.length për të përcaktuar numrin e argumenteve të kaluara në një funksion dhe më pas të përdorni çdo argument duke përdorur objektin e argumenteve.

Si shembull, merrni parasysh një funksion që lidh vargje të shumta. Argumenti i vetëm formal i funksionit është një varg që specifikon karakteret që ndajnë elementët që do të bashkohen. Funksioni përcaktohet si më poshtë:

Funksioni myConcat (ndarës) (var rezultat = ""; var i; // përsëritet përmes argumenteve për (i = 1; i< arguments.length; i++) { result += arguments[i] + separator; } return result; }

Ju mund të kaloni çdo numër argumentesh në këtë funksion dhe ai do të bashkojë çdo argument në një varg.

// kthen "e kuqe, portokalli, blu," myConcat (",", "e kuqe", "portokalli", "blu"); // kthen "elefant; gjirafë; luan; gatopard;" myConcat (";", "elefant", "gjirafë", "luan", "cheetah"); // kthen "sherebel. borzilok. rigon. piper. majdanoz." myConcat (.", "sherebele", "borzilok", "rigon", "piper", "majdanoz");

Sepse argumentet është një pseudo-varg, disa metoda vargu janë të zbatueshme për të, për shembull, për .. në

Funksioni func () (për (vlera në argumente) (console.log (vlera);)) func (1, 2, 3); // 1 // 2 // 3

Shënim: argumentet është një pseudo-varg, por jo një grup. Është një pseudo-varg që ka indekse të numëruara dhe një veti gjatësie. Megjithatë, nuk i ka të gjitha metodat e grupit.

Parametrat e pushimit

Futja e funksioneve me shigjeta u ndikua nga dy faktorë: funksionet më të shkurtra dhe fjalori i kësaj.

Funksione më të shkurtra

Në disa modele funksionale, inkurajohet përdorimi i funksioneve më të shkurtra. Krahaso:

Var a = ["Hidrogjen", "Helium", "Litium", "Berillium"]; var a2 = a.hartë (funksioni (s) (kthimi s.length;)); konsol.log (a2); // logs var a3 = a.map (s => s.length); konsol.log (a3); // regjistrat

Fjalor ky

Përpara funksioneve me shigjeta, çdo funksion i ri përcaktoi vlerën e tij (një objekt i ri në rastin e një konstruktori, i papërcaktuar në modalitetin strikte, një objekt konteksti nëse funksioni thirret si metodë e një objekti, etj.). Kjo doli të jetë e bezdisshme nga pikëpamja e stilit të programimit të orientuar drejt objektit.

Funksioni Person () (// Konstruktori Person () e përcakton "this" si vetë.this.age = 0; setInterval (funksioni growUp () (// Pa modalitetin e rreptë, growUp () e përcakton "këtë" // si një globale objekt i cili është i ndryshëm nga "this" // i përcaktuar nga konstruktori Person (). this.age ++;), 1000);) var p = Person i ri ();

Në ECMAScript 3/5, ky problem u rregullua duke i caktuar vlerën e kësaj një ndryshoreje që mund të mbyllet.

Funksioni Person () (var self = this; // Disa njerëz zgjedhin "that" në vend të" veten". // Zgjidhni një gjë dhe jini të qëndrueshëm për veten. mosha = 0; setInterval (funksioni growUp () (// Thirrja i referohet tek ndryshorja `self` e së cilës // vlera është objekti i pritur. self.age ++;), 1000);)

Shihni gjithashtu Funksionin në Referencën JavaScript për më shumë informacion mbi funksionin si objekt.

Çdo programues e di mirë se cilat janë funksionet dhe pse janë të nevojshme. Sidoqoftë, funksionet në Javascript kanë disa veçori. Nëse keni qenë duke programuar në këtë gjuhë të veçantë për një kohë të gjatë, atëherë me siguri e dini se ka të ndryshme. Nëse vini nga një gjuhë tjetër, atëherë duke lexuar disa nga artikujt, me shumë mundësi keni parë këtë, në shikim të parë, deklaratë të çuditshme të një funksioni:

Var add = funksion (arg1, arg2) (var sum = arg1 + arg2; kthe shuma;) var rezultat = add (5, 2); // rezultati tani është 7

Domethënë, funksioni, para së gjithash, nuk ka emër. Së dyti, i caktohet një ndryshoreje, por jo vetëm i caktuar, por trupi i saj shkon menjëherë. Personalisht, për mua, i cili më parë kisha shkruar në gjuhë të tilla si VB, C ++, një deklaratë e tillë shkaktoi hutim dhe keqkuptim se si funksionon dhe pse ta shkruaj fare kështu.

Jam mësuar me deklarimin dhe thirrjen e funksionit "klasik", si kjo:

Funksioni add (arg1, arg2) (var sum = arg1 + arg2; kthe shuma;) var rezultat = add (5, 3); // rezultati tani është 8

Dhe këtu vijmë te veçoritë e funksioneve në Javascript. Për lehtësinë e të kuptuarit, imagjinoni që një funksion në JS është një vlerë e zakonshme, si një numër ose një varg. A mund të shkruani numrin 5 në ndryshoren e rezultatit? Apo diçka më komplekse, si një grup, dhe pastaj ta shfaqë atë në ekran? Ti mundesh. Pra, nëse imagjinojmë që një funksion është një vlerë e zakonshme, megjithëse një strukturë shumë komplekse, atëherë mënyra e parë e deklarimit të tij nuk duket më si diçka e pabesueshme.

Fakti tjetër interesant është një vazhdim logjik i të parit. Pasi t'i vendosim të dhënat në një variabël, ne mund t'i transferojmë të dhënat në një variabël tjetër përmes emrit të kësaj ndryshore:

Var a = 5; var b = a; alarmi (b); // do të printojë 5

Gjëja e zakonshme. Tani hidhini një sy këtij kodi:

Var add = funksion (arg1, arg2) (var sum = arg1 + arg2; kthe shuma;) var calcSum = add; alarmi (calcSum (5, 6)); // printime 11

A keni filluar tashmë të hamendësoni? Meqenëse një funksion është si një ndryshore, ne mund ta "shumëzojmë" atë me anë të caktimit të zakonshëm në ndryshore të tjera, duke i kthyer ato gjithashtu në funksione. Tani calcSum mund të shtojë edhe dy numra. Megjithatë kodi

Var calcSum = shtoni (1, 1); // calcSum tani është e barabartë me 2, ky nuk është një funksion, por një variabël me një alarm numrash (calcSum (5, 6)); //gabim

Nuk do të ekzekutohet, sepse në rreshtin e parë nuk kemi caktuar vetë funksionin, por rezultatin e ekzekutimit të tij (kllapat tregojnë se duhet të ekzekutojmë funksionin, jo ta caktojmë atë).

Nëse duhet të thërrisni një funksion në vetvete, atëherë kjo bëhet si më poshtë:

Var calcFact = fakti i funksionit (val) (nëse (val == 1)? Val: val * fakt (val - 1); // llogaritja e faktorialit duke përdorur rekursionin) alarmi (calcFact (4)); // printime 24

Këtu, duke i caktuar një funksion një ndryshoreje, i kemi dhënë emrin fakt. Megjithatë, ky emër do të jetë i disponueshëm vetëm brenda vetë funksionit dhe askund tjetër. Arsyet për këtë qëndrojnë në parimin e përkthyesit dhe janë përtej qëllimit të mësimit.

Ju mund të pyesni veten: "Hmm, një mundësi interesante! Por cili është avantazhi i kësaj metode? A ka situata ku nuk mund të bëhet pa të, ose është të paktën më i përshtatshëm se një reklamë e zakonshme?" Nuk do të marr përsipër të argumentoj se ka situata ku një qasje e tillë nuk mund të përjashtohet, por mund të jap një shembull ku zvogëlon sasinë e kodit. Le të themi se duhet të përshëndesësh një person në varësi të kohës së ditës:

Var data = data e re (); var hello = (data.getHours ()< 12) ? function() {alert("Доброе утро!")} : (date.getHours() < 18) ? function() {alert("Добрый день!")} : function() {alert("Добрый вечер!")}; hello();

Siç mund ta shihni, funksionet janë jashtëzakonisht të thjeshta, me një komandë të vetme alarmi.

Nëse do të vendosnim të shkonim në "rrugën klasike", atëherë do të na duhej të shkruanim tre funksione të veçanta dhe më pas t'i thërrasim ato në një kusht kontrolli kohor:

Funksioni GoodMorning () (alarm ("Mirëmëngjes!");) Funksioni mirëPasdite () (Alert ("Mirëdita!");) Funksioni GoodEvning () (Alert ("Mirëmbrëma!");) Var data = data e re (); (data.getHours ()< 12) ? goodMorning() : (date.getHours() < 18) ? goodAfternoon() : goodEvning();

Kodi është rritur ndjeshëm vizualisht, edhe duke marrë parasysh që kemi përdorur një formë të shkurtër shënimi për operatorin e kushtëzuar. Nëse supozojmë se skedari përmban funksione vërtet të rëndësishme që kryejnë llogaritjet, atëherë mbushja e listës me mini-funksione të tilla që nuk kanë logjikë të rëndësishme dhe që përdoren, me shumë mundësi, vetëm një herë, nuk është një ide e mirë. Përveç kësaj, ne jemi të detyruar t'i japim secilit funksion një emër unik dhe ta tregojmë atë kur telefononi. Prandaj, nëse keni nevojë të ndryshoni emrin e njërit prej tyre, do të duhet ta ndryshoni atë në dy vende, gjë që rrit mundësinë e një gabimi.

Së dyti, nëse përdorim metodën "klasike", atëherë humbasim aftësinë për t'i caktuar një funksion një ndryshoreje. Domethënë shkruani

Funksioni add (a, b) (ktheje a + b;) var calcSum = add; calcSum (5, 5);

Nuk është më e mundur. Prandaj, në shembullin tonë, nëse ende duhet të përshëndesim mysafirin më shumë se një herë, do të duhet ta kopjojmë këtë fragment çdo herë:

(data.getHours ()< 12) ? goodMorning() : (date.getHours() < 18) ? goodAfternoon() : goodEvning();

Dhe në rastin e parë, do të jetë e mjaftueshme të shkruani vetëm përshëndetje (); dhe rezultati do të jetë i njëjtë.

Ju tregova për një veçori interesante të funksioneve JS dhe dhashë shembuj. Kështu e patë mënyra për të thirrur funksione në Javascript nuk kufizohen në një specie të vetme. Edhe nëse nuk mund të gjeni menjëherë aplikim për këto mundësi në projektet tuaja, të paktën do ta dini se ka mundësi të tilla. Dhe kur të vijë fati vërtet i mirë, mund të zvogëloni sasinë e kodit dhe të shmangni konfuzionin dhe gabimet e panevojshme!

Ky artikull përshkruan funksionet e nivelit të gjuhës Javascript: krijimi, parametrat, truket, mbylljet dhe më shumë.

Krijimi i funksioneve

Ekzistojnë 3 mënyra për të krijuar një funksion. Dallimi kryesor si rezultat i punës së tyre është se funksioni i emërtuar është i dukshëm kudo, dhe ai anonim është i dukshëm vetëm pas deklarimit:

Funksionet - objektet

Në javascript, funksionet janë objekte të plota të klasës së integruar Function. Kjo është arsyeja pse ato mund t'u caktohen variablave, të kalohen dhe, natyrisht, ato kanë veti:

Funksioni f () (...) f.test = 6 ... alarm (f.test) // 6

Vetitë e funksionit janë gjithashtu të disponueshme brenda funksionit, kështu që ato mund të përdoren si variabla statike.

Për shembull,

Funksioni func () (var funcObj = argumentet.callee funcObj.test ++ alarmi (funcObj.test)) func.test = 1 func () func ()

Në fillim, çdo funksion krijon një variabël argumentesh brenda vetes dhe i cakton argumentet.callee një referencë për vete. Pra arguments.callee.test është një veti e func.test, pra testi i variablës statike.

Në shembull, detyra nuk mund të bëhej:

Var test = argumente.callee.test test ++

pasi në këtë rast operacioni ++ do të kishte funksionuar në testin e ndryshores lokale, dhe jo në vetinë e testimit të objektit të funksionit.

Objekti i argumenteve gjithashtu përmban të gjitha argumentet dhe mund të konvertohet në një grup (megjithëse nuk është), shih më poshtë në seksionin mbi parametrat.

Fushëveprimi

Çdo funksion, ose më mirë edhe çdo nisje e një funksioni, përcakton qëllimin e vet individual.

Variablat mund të deklarohen kudo. Fjala kyçe var vendos një variabël në shtrirjen aktuale. Nëse e harroni atë, atëherë ndryshorja do të shkojë në objektin e dritares globale. Janë të mundshme kryqëzime të papritura me variabla të tjerë të dritareve, konflikte dhe defekte.

Ndryshe nga një numër gjuhësh, blloqet nuk përcaktojnë një fushë të veçantë. Nuk ka dallim nëse një variabël përcaktohet brenda ose jashtë bllokut. Pra, këto dy fragmente janë krejtësisht ekuivalente:

Një variabël i specifikuar përmes var është i dukshëm kudo në shtrirje, madje edhe përpara deklaratës var. Për shembull, le të bëjmë një funksion që do të ndryshojë variablin, var për të cilin ndodhet më poshtë.

Për shembull:

Funksioni a () (z = 5 // ndryshoni z në nivel lokal .. // .. sepse z deklarohet nëpërmjet var var z) // testoni fshirjen z // pastroni za () globale vetëm në rast alarmi (dritare.z) // => e papërcaktuar sepse z u ndryshua në nivel lokal

Parametrat e funksionit

Funksionet mund të ekzekutohen me çdo numër parametrash.

Nëse funksionit i kalohen më pak parametra sesa janë në përkufizim, atëherë ato që mungojnë konsiderohen të papërcaktuara.

Funksioni i mëposhtëm kthen kohën e nevojshme për të mbuluar distancën me shpejtësi uniforme.

Në nisjen e parë, funksioni funksionon me argumente distancë = 10, shpejtësi = e papërcaktuar. Në mënyrë tipike, kjo situatë, nëse mbështetet nga funksioni, siguron një vlerë të paracaktuar:

// nëse shpejtësia është një vlerë false (e pacaktuar, 0, e gabuar ...) - zëvendëso 10 shpejtësi = shpejtësi || 10

Operatori || në javascript nuk kthen true / false, por vetë vlerën (e para, e cila është hedhur në true).

Prandaj, përdoret për të vendosur vlerat e paracaktuara. Në thirrjen tonë, shpejtësia do të jetë e papërcaktuar || 10 = 10.

Prandaj, rezultati do të jetë 10/10 = 1.

Lëshimi i dytë është standard.

Drejtimi i tretë jep disa argumente shtesë. Funksioni nuk parashikon punë me argumente shtesë, kështu që ato thjesht injorohen.

Epo, në rastin e fundit, nuk ka fare argumente, kështu që distanca = e papërcaktuar, dhe rezultati i ndarjes është i papërcaktuar / 10 = NaN (Jo-Numër, ka ndodhur një gabim).

Puna me një numër të pacaktuar parametrash

Pak para se të futet në trupin e funksionit, krijohet automatikisht një objekt argumentesh që përmban

  1. Thirrni argumentet duke filluar nga zero
  2. Gjatësia në vetinë gjatësi
  3. Një referencë për vetë funksionin në pronën e thirrësit

Për shembull,

Funksioni func () (për (var i = 0; i

Vetia e argumenteve është si një grup në atë që ka një gjatësi dhe indekse numerike. Në fakt, argumentet nuk i përkasin klasës Array dhe nuk përmbajnë metodat e saj si push, pop dhe të tjera.

Nëse ende dëshironi të përdorni këto metoda, për shembull, për të thirrur një funksion tjetër me të njëjtat argumente, por përveç të parës, mund të krijoni një grup të vërtetë nga argumentet:

Var args = Array.prototype.slice.thirrje (argumente) // .. tani args është një grup real argumentesh .. args.shift () ...

Ju mund të thërrisni një funksion në një grup argumentesh duke përdorur aplikacionin:

Var func = funksion (a, b) (alarm (a + b)) var arr = func.aplikoj (null, arr) // => alarm (3)

Një shembull i kalimit të një funksioni me referencë

Një funksion mund të kalohet lehtësisht si argument në një funksion tjetër.

Për shembull, harta merr funksionin funksion, e zbaton atë në secilin element në grupin arr dhe kthen grupin që rezulton:

Var hartë = funksion (func, arr) (var rezultat = për (var i = 0; i

Shembull përdorimi:

Harta (drejtuar,) // =

Ose, mund të krijoni një funksion anonim direkt në thirrjen në hartë:

// Funksioni anonim trefishon hartën e numrave (funksioni (a) (kthe një * 3),) // =

Palosja e parametrave në një objekt

Ka funksione, argumentet e të cilëve ndryshojnë shumë.

Për shembull:

// mund të specifikoni vetëm një pjesë të argumenteve // ​​të paspecifikuara - janë llogaritur ose merren sipas funksionit të paracaktuar ndryshimi i madhësisë (në Gjerësi, në Lartësi, SaveProportions, animate) (// vlerat e paracaktuara'SaveProportions = saveProportions || animate e vërtetë = animate | | e vërtetë për Lartësinë = për Lartësinë | | ...)

Një thirrje me parametra opsionale duhet të bëhet si kjo:

Ndryshimi i madhësisë (100, null, null, i vërtetë)

Për të shmangur null-et e panevojshme dhe për ta bërë kodin më të lexueshëm, përdorni diçka si "argumentet e fjalëve kyçe" që ekzistojnë në Python dhe Ruby. Për këtë, shumë parametra paketohen në një objekt të vetëm:

Ndryshimi i madhësisë së funksionit (konfigurimi) (// vlerat e paracaktuara var saveProportions = setup.saveProportions || var animate e vërtetë = setup.animate || var e vërtetë nëHeight = setup.toHeight || ...)

Thirrja tani është shumë më e lehtë:

Konfigurimi var = (në Gjerësinë: 100, animoni: e vërtetë) ndryshoni madhësinë (konfigurimin) // ose ndryshoni madhësinë ((në gjerësinë: 100, animoni: e vërtetë))

Pra - shumë më e qartë. Dhe nëse ka më shumë se 5 parametra, atëherë në përgjithësi - mënyra e vetme normale.

Për më tepër, është më i përshtatshëm për të bërë një sekuencë thirrjesh me një objekt si:

Konfigurimi var = (në gjerësinë: 100, animate: e vërtetë, ruajProporcionet: false) ndryshimi i madhësisë (konfigurimi) konfigurimi.toWidth = 200 ndryshimi i madhësisë (konfigurimi)

Funksione

Funksioniështë një bllok i kodit JavaScript që përcaktohet një herë dhe mund të ekzekutohet, ose thirret, disa herë. Ju mund të jeni tashmë të njohur me një funksion me një emër tjetër, të tillë si një nënprogram ose procedurë. Funksionet mund të kenë parametra: një përkufizim funksioni mund të përfshijë një listë identifikuesish, të cilët quhen parametra dhe veprojnë si variabla lokale në trupin e funksionit.

Kur thirrni funksione, atyre mund t'u kalohen vlera ose argumente që korrespondojnë me parametrat e tyre. Funksionet shpesh përdorin argumentet e tyre për të vlerësuar vlerën e kthyer, e cila është vlera e shprehjes së thirrjes së funksionit. Përveç argumenteve, kur thirrni ndonjë funksion, atij i kalohet një vlerë tjetër që përcakton kontekstin e thirrjes - vlerën në fjalën kyçe kjo.

Funksionet në JavaScript janë objekte dhe mund të përdoren në mënyra të ndryshme. Për shembull, funksionet mund t'u caktohen variablave dhe t'u kalohen funksioneve të tjera. Meqenëse funksionet janë objekte, është e mundur të caktohen vlera në vetitë e tyre dhe madje të thirren metodat e tyre.

JavaScript ju lejon të krijoni përkufizime funksionesh që janë të vendosura brenda funksioneve të tjera, dhe funksione të tilla do të kenë akses në të gjitha variablat e pranishme në fushëveprimin e përkufizimit.

Përcaktimi i funksioneve

Përkufizimi i funksionit fillon me një fjalë kyçe funksionin e ndjekur nga komponentët e mëposhtëm:

Një identifikues që përcakton emrin e funksionit

Emri është një pjesë e nevojshme e deklaratës së deklaratës së funksionit: do të përdoret për të krijuar një variabël të ri të cilit do t'i caktohet objekti i ri i funksionit. Emri mund të mungojë në shprehjet e përkufizimit të funksionit: nëse është i pranishëm, emri do t'i referohet objektit të funksionit vetëm në trupin e vetë funksionit.

Një palë kllapa rreth një liste me zero ose më shumë identifikues, të ndarë me presje

Këta identifikues do të përcaktojnë emrat e parametrave të funksionit dhe mund të përdoren si variabla lokale në trupin e funksionit.

Një palë kllapa kaçurrela me zero ose më shumë deklarata JavaScript brenda

Këto udhëzime përbëjnë trupin e funksionit: ato ekzekutohen sa herë që thirret funksioni.

Shembulli i mëposhtëm tregon disa përkufizime funksionesh si deklarata dhe shprehje. Vini re se përkufizimet e funksioneve si shprehje janë të dobishme vetëm nëse ato janë pjesë e shprehjeve më të mëdha, të tilla si caktimet ose thirrjet e funksioneve, që bëjnë diçka me një funksion të sapodeklaruar:

// Printon emrat dhe vlerat e të gjitha vetive të funksionit të objektit obj printprops (obj) (për (var p në obj) console.log (p + ":" + obj [p] + "\ n"); ) // Llogarit distancën ndërmjet pikave (x1, y1) dhe (x2, y2) distancën e funksionit (x1, y1, x2, y2) (var dx = x2 - x1; var dy = y2 - y1; kthen Math.sqrt ( dx * dx + dy * dy );) // Funksioni rekurziv (duke thirrur veten) që llogarit funksionin faktorial faktorial (x) (nëse (x

Vini re se emri i funksionit mund të mos jetë i pranishëm në shprehjet e përkufizimit të funksionit. Një deklaratë e deklarimit të funksionit në të vërtetë deklaron një variabël dhe i cakton një objekt funksioni asaj.

Në të kundërt, një shprehje e përkufizimit të funksionit nuk deklaron një ndryshore. Megjithatë, në shprehjet e përkufizimit, lejohet të specifikohet emri i funksionit, si në funksionin për llogaritjen e faktorialit të mësipërm, i cili mund të kërkohet në trupin e funksionit për të thirrur veten. Nëse shprehja e përkufizimit të funksionit përfshin një emër, emri i dhënë do t'i referohet objektit të funksionit në fushëveprimin e atij funksioni. Në fakt, emri i funksionit bëhet një ndryshore lokale, e aksesueshme vetëm në trupin e funksionit. Në shumicën e rasteve, emri i funksionit nuk ka nevojë të specifikohet në shprehjet e përkufizimit, gjë që i bën përkufizimet më kompakte.

Vini re se shumica (por jo të gjitha) e funksioneve në shembull përmbajnë një deklaratë kthimi. Deklarata e kthimit përfundon ekzekutimin e funksionit dhe kthen vlerën e shprehjes së tij (nëse specifikohet) në programin thirrës. Nëse nuk ka shprehje në deklaratën e kthimit, ajo kthehet e papërcaktuar. Nëse nuk ka deklaratë kthimi në funksion, interpretuesi thjesht do të ekzekutojë të gjitha deklaratat në trupin e funksionit dhe do të kthehet të papërcaktuar në programin thirrës.

Shumica e funksioneve në shembull vlerësojnë disa vlera dhe përdorin një deklaratë kthimi për ta kthyer atë vlerë në programin thirrës. Funksioni printprops () është paksa i ndryshëm në këtë kuptim: detyra e tij është të printojë emrat e vetive të një objekti. Nuk ka nevojë të kthejë ndonjë vlerë, kështu që nuk ka asnjë deklaratë kthimi në funksion. Funksioni printprops () do të kthehet gjithmonë i papërcaktuar. (Funksionet që nuk kanë një vlerë të kthimit quhen ndonjëherë procedura.)

Funksionet e thirrjes

Kodi i programit që formon trupin e funksionit nuk ekzekutohet në momentin e përcaktimit të funksionit, por në momentin kur thirret. Thirrjet e funksionit kryhen duke përdorur një shprehje thirrjeje. Një shprehje thirrje përbëhet nga një shprehje thirrje funksioni që kthen një objekt funksioni, e ndjekur nga kllapat e ndjekur nga një listë me zero ose më shumë shprehje argumentesh, të ndara me presje, brenda.

Nëse shprehja e thirrjes së funksionit është një shprehje e thirrjes së vetive - nëse funksioni është një veti e një objekti ose një elementi i një grupi (domethënë një metodë) - atëherë shprehja e thirrjes është një shprehje e thirrjes së metodës. Fragmenti i mëposhtëm demonstron disa shembuj të shprehjeve të thirrjes së funksionit të zakonshëm:

Pajisjet e printimit ((x: 4, mosha: 24)); var d = distanca (1,1,5,6); var f = faktorial (5) / faktorial (12); f = katror (5);

Kur thirret funksioni, të gjitha shprehjet e argumenteve (të specifikuara midis kllapave) vlerësohen dhe vlerat që rezultojnë përdoren si argumente për funksionin. Këto vlera u caktohen parametrave, emrat e të cilëve janë të shënuar në përkufizimin e funksionit. Në trupin e një funksioni, shprehjet e thirrjes së parametrave kthejnë vlerat e argumenteve përkatëse.

Kur thirret një funksion normal, vlera e kthyer e funksionit bëhet vlera e shprehjes thirrëse. Nëse funksioni kthehet kur interpretuesi arrin fundin e tij, vlera e kthyer është e papërcaktuar. Nëse një funksion kthehet si rezultat i një deklarate kthyese, vlera e shprehjes pas deklaratës së kthimit kthehet, ose e padefinuar nëse deklarata e kthimit nuk ka shprehje.

Metoda nuk është gjë tjetër veçse një funksion që ruhet si veti e një objekti. Nëse keni një funksion funksioni dhe një objekt obj, mund të përcaktoni një metodë në metodën e quajtur objekti obj, siç tregohet më poshtë:

// Përcaktoni një objekt dhe funksion të thjeshtë var obj = (); funksioni func (a, b) (kthejeni a + b;) // Shtoni metodën obj në objektin obj.metod = func; // Tani mund ta quani këtë metodë var result = obj.method (4, 5);

Më shpesh, kur thirrni metoda, përdorni formën e hyrjes në pronat duke përdorur operatorin e pikave, por në të njëjtën mënyrë mund të përdorni formën e aksesit të vetive duke përdorur kllapa katrore. Për shembull, të dyja shprehjet e mëposhtme janë shprehje të thirrjes së metodës:

Rezultati = obj.metoda (4, 5); rezultat = obj ["metodë"] (4, 5);

Argumentet dhe vlera e kthyer e një thirrjeje metode trajtohen në të njëjtën mënyrë si një thirrje funksioni të rregullt. Sidoqoftë, thirrja e metodës ka një ndryshim të rëndësishëm: kontekstin e thirrjes. Një shprehje e aksesit të pronës përbëhet nga dy pjesë: një objekt (në këtë rast obj) dhe një emër pronësie (metodë). Në shprehje të tilla thirrjeje të metodës, objekti obj bëhet konteksti thirrës dhe trupi i funksionit është në gjendje t'i referohet këtij objekti duke përdorur fjalën kyçe this. Për shembull:

Var obj = (x: 0, y: 0, // Metoda e mbledhjes: funksioni (a, b) (this.x = a; this.y = b;), // Një metodë tjetër shuma: funksioni () (kthejeni këtë .x + kjo.y)); // Metodat e thirrjes obj.add (15, 4); konsol.log (obj.sum ()); // nëntëmbëdhjetë

Metodat dhe kjo fjalë kyçe janë qendrore për paradigmën e programimit të orientuar nga objekti. Çdo funksion i përdorur si metodë në fakt merr një argument të nënkuptuar - objektin në të cilin është thirrur. Në mënyrë tipike, metodat kryejnë disa veprime në një objekt dhe sintaksa e thirrjes së metodës pasqyron qartë faktin që një funksion vepron në një objekt.

Shënim: kjo është vetëm një fjalë kyçe, jo një variabël ose emër pronësie. Sintaksa JavaScript nuk lejon caktimin e vlerave në këtë element.

Argumentet dhe parametrat e funksionit

Në JavaScript, llojet e parametrave nuk specifikohen në përkufizimet e funksioneve dhe nuk kryhen kontrolle të tipit në vlerat e argumenteve të kaluara kur thirren funksionet. Në fakt, kur thirrni funksione në JavaScript, as numri i argumenteve nuk kontrollohet. Nënseksionet më poshtë përshkruajnë se çfarë ndodh kur numri i argumenteve në një thirrje funksioni është më i vogël ose më shumë se numri i parametrave të deklaruar. Ato tregojnë gjithashtu se si mund të kontrolloni në mënyrë eksplicite llojet e argumenteve të një funksioni nëse duhet të siguroheni që funksioni të mos thirret me argumente të pavlefshme.

Argumente Fakultative

Kur numri i argumenteve në një thirrje funksioni është më i vogël se numri i parametrave të deklaruar, argumentet që mungojnë janë të papërcaktuara. Shpesh është i përshtatshëm për të shkruar funksione në mënyrë që disa nga argumentet të jenë opsionale dhe të mund të hiqen kur thirret funksioni. Në këtë rast, është e dëshirueshme të parashikohet mundësia e caktimit të vlerave të paracaktuara të arsyeshme të arsyeshme për parametrat që mund të anashkalohen. Për shembull:

// Shtoni emrat e numëruar // të vetive të objektit obj në grupin arr dhe kthejeni atë. Nëse argumenti // arr nuk u kalua, krijoni dhe ktheni një funksion të ri të grupit getPropertyNames (obj, / * opsionale * / arr) (nëse (arr === i papërcaktuar) arr =; // Nëse grupi nuk është i përcaktuar, krijoni një i ri për ( vetia var në obj) arr.push (veti); ktheje arr;) // Ky funksion mund të thirret me 1 ose 2 argumente: var a = getPropertyNames ((x: 1, y: 1)); // Merrni vetitë e objektit në një grup të ri getPropertyNames ((z: 5), a); // shtoni vetitë e objektit të ri në këtë panel konsolë.log (a); // ["x", "y", "z"]

Vini re se kur deklaroni funksione, argumentet opsionale duhet të përfundojnë listën e argumenteve që do të hiqet. Programuesi që do t'i shkruajë një thirrje funksionit tuaj nuk do të jetë në gjendje të kalojë argumentin e dytë dhe në të njëjtën kohë të heqë të parin: ai do të detyrohet të kalojë në mënyrë eksplicite të papërcaktuar në argumentin e parë. Vini re gjithashtu komentin / * opsional * / në përkufizimin e funksionit, i cili thekson faktin që parametri është opsional.

Listat e argumenteve me gjatësi të ndryshueshme

Nëse numri i argumenteve në një thirrje funksioni tejkalon numrin e emrave të parametrave, funksioni nuk lejohet të aksesojë drejtpërdrejt vlerat e paemërtuara. Zgjidhja e këtij problemi ofron Argumentet objekt... Në trupin e funksionit, identifikuesi argumentet i referohet objektit Argumentet i pranishëm në thirrje. Objekti i Argumenteve është një objekt i ngjashëm me grupin që ju lejon të rikuperoni vlerat e transferuara në një funksion nga numrat e tyre, në vend të emrit.

Supozoni se funksioni është përcaktuar që kërkon një argument, x. Nëse e quani këtë funksion me dy argumente, atëherë i pari do të jetë i disponueshëm brenda funksionit me emrin e parametrit x ose si argumente. Argumenti i dytë do të jetë i disponueshëm vetëm si argumente. Përveç kësaj, si vargjet reale, argumentet kanë një veti gjatësie që përcakton numrin e elementeve që duhet të përmbajnë. Kjo do të thotë, në trupin e funksionit të quajtur me dy argumente, argumentet.gjatësia është 2.

Objekti Arguments mund të përdoret për një larmi qëllimesh. Shembulli i mëposhtëm tregon se si ta përdorni atë për të kontrolluar nëse një funksion është thirrur me numrin e saktë të argumenteve, pasi JavaScript nuk do ta bëjë këtë për ju:

Funksioni funksion (x, y, z) (// Së pari, kontrollon nëse numri i saktë i argumenteve është kaluar nëse (arguments.length! = 3) (hedh gabim të ri ("Funksioni funksioni u thirr me" + argumentet.length + "argumente, por 3. ");) // Dhe tani vetë kodi i funksionit ...)

Vini re se shpesh është e panevojshme të kontrolloni numrin e argumenteve, si në këtë shembull. Sjellja e paracaktuar e interpretuesit JavaScript është e shkëlqyer për shumicën e rasteve: argumentet që mungojnë zëvendësohen me të papërcaktuara dhe argumentet shtesë thjesht shpërfillen.

Objekti Arguments ilustron një veçori të rëndësishme të funksioneve JavaScript: ato mund të shkruhen për të marrë çdo numër argumentesh. Funksioni i mëposhtëm merr çdo numër argumentesh dhe kthen vlerën e më të madhit prej tyre (funksioni i integruar Math.max () sillet në mënyrë të ngjashme):

Funksioni maxNumber () (var m = Number.NEGATIVE_INFINITY; // Hapni të gjitha argumentet, gjeni dhe // ruajeni më të madhin prej tyre për (var i = 0; im) m = argumentet [i]; // Ktheni kthimin më të madh m ;) var më i madhi = maxNumri (1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6); // 10000

Funksionet si ky, të cilët mund të marrin një numër arbitrar argumentesh, quhen funksione variadike, funksione aritie të ndryshueshme ose funksione varargs. Ky term filloi me ardhjen e gjuhës së programimit C.

Vini re se funksionet me një numër të ndryshueshëm argumentesh nuk duhet të thirren me një listë të zbrazët të argumenteve. Ka kuptim të plotë të përdoret objekti i argumenteve kur shkruani një funksion që pret të marrë një numër fiks të argumenteve të kërkuara me emër, të ndjekur nga një numër arbitrar i argumenteve opsionale të paemërtuar.

Mbani në mend se argumentet nuk janë në fakt një grup - ato janë një objekt Argumenti. Çdo objekt Argumente ka elemente të grupit të numëruar dhe një veçori gjatësie, por teknikisht nuk është një grup. Më mirë ta mendojmë atë si një objekt me disa veti të numëruara.

Përveç elementeve të grupit të tij, objekti Arguments përcakton vetitë thirrës dhe telefonuesi... Përpjekja për të ndryshuar vlerat e këtyre vetive në modalitetin e rreptë ECMAScript 5 është i garantuar që të lëshojë një përjashtim TypeError. Megjithatë, në modalitetin e dobët, standardi ECMAScript thotë se vetia e thirrësit i referohet funksionit aktualisht ekzekutiv. Vetia e thirrësit nuk është standarde, por është e pranishme në shumë implementime dhe i referohet funksionit që thirri atë aktual.

Vetia e thirrësit mund të përdoret për të hyrë në grupin e thirrjeve dhe vetia e thirrësit është veçanërisht e dobishme për thirrjen rekursive të funksioneve të paemërtuara:

Var faktorial = funksioni (x) (nëse (x

Vetitë dhe metodat e funksioneve

Ne kemi parë që funksionet mund të përdoren si vlera në programet JavaScript. Operatori tipof kthen vargun "funksion" për funksionet, por funksionet në JavaScript janë në fakt një lloj i veçantë objekti. Dhe meqenëse funksionet janë objekte, ato kanë veti dhe metoda si çdo objekt tjetër. Ekziston edhe një konstruktor Funksioni () që krijon objekte të reja funksioni. Nënseksionet e mëposhtme përshkruajnë vetitë dhe metodat e funksioneve.

Prona e gjatësisë

Në trupin e funksionit, vetia arguments.length përcakton numrin e argumenteve që i kalohen funksionit. Sidoqoftë, vetia e gjatësisë së vetë funksionit ka një kuptim tjetër. Kjo veti vetëm për lexim kthen numrin e argumenteve që funksioni pret të marrë - numrin e parametrave të deklaruar.

Pjesa e mëposhtme përcakton një funksion të quajtur check () që merr një grup argumentesh nga një funksion tjetër. Ai krahason vetinë arguments.length (numrin e argumenteve të miratuara në të vërtetë) me vetinë arguments.callee.length (numrin e argumenteve të pritura) për të përcaktuar nëse funksionit i janë dhënë aq argumente sa ai pret. Nëse vlerat nuk përputhen, bëhet një përjashtim. Funksioni i kontrollit () pasohet nga funksioni i testit të funksionit () i cili demonstron se si të përdoret funksioni i kontrollit ():

// Ky funksion përdor arguments.callee, kështu që // nuk do të funksionojë në kontrollin e funksionit të modalitetit të rreptë (args) (var actual = args.length; // Numri aktual i argumenteve var pritet = args.callee.length; // Argumentet e numrit të pritshëm nëse (aktual! == i pritshëm) // Nëse nuk përputhen, hidhni Gabim të ri ("pritur:" + pritet + "; marrë" + aktual);) funksioni funksion (x, y, z) (/ / Kontrolloni numrin e argumenteve të pritshme dhe kontrollin e kaluar në të vërtetë (argumentet); // Tani ekzekutoni pjesën tjetër të funksionit kthim x + y + z;)

Prona e prototipit

Çdo funksion ka një veti prototip që i referohet një objekti të njohur si një objekt prototip. Çdo funksion ka objektin e tij prototip. Kur një funksion përdoret si konstruktor, objekti i krijuar rishtazi trashëgon vetitë e atij objekti prototip.

Prototipet dhe vetia e prototipit u diskutuan në artikullin e mëparshëm.

Thirrni () dhe aplikoni metodat ().

Metodat e thirrjes () dhe aplikimit () ju lejojnë të thërrisni në mënyrë indirekte një funksion sikur të ishte një metodë e ndonjë objekti tjetër. Argumenti i parë për të thirrur () dhe për të aplikuar () është objekti në të cilin thirret funksioni; ky argument përcakton kontekstin e thirrjes dhe bëhet vlera e fjalës kyçe this në trupin e funksionit. Për të thirrur funksionin () (pa argumente) si metodë obj, mund të përdorni njërën nga metodat e thirrjes () ose të aplikoni ():

Func.thirrje (obj); func.aplikoj (obj);

Secila prej këtyre metodave të thirrjes është ekuivalente me fragmentin e mëposhtëm (duke supozuar se obj nuk ka një veti të quajtur m):

Obj.m = func; // Bëje përkohësisht func metodën obj obj.m (); // E quaj pa argumente. fshij obj.m; // Hiq metodën e përkohshme.

Në modalitetin strikte ECMAScript 5, argumenti i parë i metodave të thirrjes () dhe aplikimit () bëhet kjo vlerë, edhe nëse është një vlerë e thjeshtë, e pavlefshme ose e papërcaktuar. Në ECMAScript 3 dhe në modalitetin jo të rreptë, vlerat null dhe të papërcaktuara zëvendësohen nga objekti global, dhe vlera e thjeshtë zëvendësohet nga objekti mbështjellës përkatës.

Të gjitha argumentet e tjera të metodës së thirrjes () pas argumentit të parë që specifikon kontekstin e thirrjes i kalohen funksionit të thirrur. Metoda e aplikimit () vepron si metoda e thirrjes (), me përjashtim të faktit që argumentet e funksionit kalohen si një grup. Nëse një funksion mund të trajtojë një numër arbitrar argumentesh, metoda e aplikimit () mund të përdoret për të thirrur atë funksion në kontekstin e një vargu me gjatësi arbitrare.

Shembulli i mëposhtëm tregon një përdorim praktik të metodës së thirrjes ():

// Më poshtë janë dy funksione që shfaqin vetitë dhe // vlerat e vetive të një objekti arbitrar. Metoda e shfaqjes // kalohet si një argument funksioni func print1 (func, obj) (për (n në obj) func (n + ":" + obj [n]);) funksion print2 (func, objPajisje, obj) ( për (n në obj) func.call (objDevice, n + ":" + obj [n]);) var obj = (x: 5, y: 10); print2 (dokument.shkruaj, dokument, obj); // Punon si duhet print2 (console.log, console, obj); print1 (dokument.shkruaj, obj); // Një përjashtim i thirrjes së paligjshme do të hidhet sepse print1 (console.log, obj); // është e pamundur të quhen këto metoda pa një objekt konteksti

Metoda e lidhjes ().

Metoda bind () u shfaq për herë të parë në ECMAScript 5, por është e lehtë për t'u imituar në ECMAScript 3. Siç sugjeron emri i saj, qëllimi kryesor i metodës bind () është të lidh një funksion me një objekt. Nëse telefononi metodën bind () të funksionit dhe ia kaloni objektin obj, ai do të kthejë një funksion të ri. Thirrja e funksionit të ri (si një funksion normal) do të thërrasë funksionin origjinal të funksionit si metodë e obj. Çdo argument i kaluar në funksionin e ri do t'i kalohet funksionit origjinal. Për shembull:

// Funksioni për të lidhur funksionin func (y) (kthejeni këtë.x + y;) var obj = (x: 1); // Objekti për t'u lidhur me var g = func.bind (obj); // Thirrja e g (x) do të thërrasë obj.func (x)

Kjo mënyrë e lidhjes është e lehtë për t'u zbatuar në ECMAScript 3, siç tregohet më poshtë:

// Kthen një funksion që thërret funksionin si metodë e obj // dhe i kalon të gjitha argumentet e tij funksioni bind (func, obj) (nëse (func.bind) kthen func.bind (obj); // Përdor metodën bind, nëse është i pranishëm tjetër funksion ktheje () (// Bind tjetër si më poshtë ktheje func.apply (obj, argumente););)

Metoda bind () në ECMAScript 5 nuk lidh vetëm një funksion me një objekt. Ai gjithashtu bën aplikim të pjesshëm: përveç kësaj vlere, të gjitha argumentet e kaluara në bind () pas argumentit të tij të parë do të lidhen. Aplikimi i pjesshëm është një teknikë e zakonshme në programimin funksional dhe nganjëherë quhet karrige.

Artikujt kryesorë të lidhur