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

Programim funksional. Funksionet në JavaScript

Funksione

Funksioniështë një bllok i kodit JavaScript që përcaktohet një herë dhe mund të ekzekutohet, ose thirret, disa herë. Ju tashmë mund të jeni njohur me konceptin e "funksionit" 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ë quajtur parametra që veprojnë si variabla lokale në trupin e funksionit.

Kur thirren funksionet, atyre mund t'u kalohen vlera ose argumente që korrespondojnë me parametrat e tyre. Funksionet shpesh përdorin argumentet e tyre për të llogaritur një vlerë të kthyer, e cila është vlera e një shprehjeje të thirrjes së funksionit. Përveç argumenteve, kur thirret ndonjë funksion, i jepet një vlerë më shumë që përcakton kontekstin e thirrjes - vlera në fjalën kyçe kjo.

Funksionet në JavaScript janë objekte dhe mund të përdoren në shumë mënyra. 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 lejon që përkufizimet e funksioneve të futen 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ërkufizimi i funksionit

Një përkufizim funksioni fillon me një fjalë kyçe funksionin e ndjekur nga komponentët e mëposhtëm:

Identifikuesi që përcakton emrin e funksionit

Emri është një pjesë e detyrueshme 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. Në shprehjet e përkufizimit të funksionit, emri mund të hiqet: 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 të ndarë me presje me zero ose më shumë identifikues

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 në formën e deklaratave dhe shprehjeve. 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 një caktim ose një thirrje funksioni, që kryejnë disa veprime duke përdorur funksionin e sapodeklaruar:

// Printon emrat dhe vlerat e të gjitha vetive të funksionit të objektit obj printprops(obj) (for(var p në obj) console.log(p + ": " + obj[p] + "\n"); ( dx*dx + dy*dy ); ) // Funksioni rekurziv (duke thirrur veten) që llogarit funksionin faktorial faktorial(x) (nëse (x

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

Një shprehje e përkufizimit të funksionit, në të kundërt, nuk deklaron një ndryshore. Megjithatë, shprehjet e përkufizimit lejohen të specifikojnë një emër funksioni, si në funksionin faktorial më sipër, i cili mund të kërkohet në trupin e funksionit për të thirrur veten. Nëse një shprehje e përkufizimit të funksionit përfshin një emër, ai emër do t'i referohet objektit të funksionit në shtrirjen e funksionit. Në fakt, emri i funksionit bëhet një ndryshore lokale, e aksesueshme vetëm brenda trupit të funksionit. Në shumicën e rasteve, emri i funksionit nuk kërkohet në shprehjet e përkufizimit, duke i bërë 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'i kthehet thirrësit të papërcaktuar.

Shumica e funksioneve në shembull vlerësojnë disa vlera dhe përdorin një deklaratë kthimi për t'ia kthyer atë vlerë thirrësit. 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ë asnjë 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 një funksioni nuk ekzekutohet në momentin e përcaktimit të funksionit, por në momentin kur thirret. Thirrjet e funksionit bëhen duke përdorur një shprehje thirrjeje. Një shprehje thirrëse përbëhet nga një shprehje e thirrjes së funksionit që kthen një objekt funksioni, e ndjekur nga kllapa me një listë të ndarë me presje me zero ose më shumë shprehje argumentesh brenda.

Nëse një shprehje e aksesit të funksionit është një shprehje e aksesit të veçorive - nëse funksioni është një veti e një objekti ose një elementi i një grupi (dmth., një metodë) - atëherë shprehja e thirrjes është një shprehje e thirrjes së metodës. Pjesa e mëposhtme demonstron disa shembuj të shprehjeve të thirrjes së funksionit normal:

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 një funksion, të gjitha shprehjet e argumenteve (të specifikuara midis kllapave) vlerësohen dhe vlerat që rezultojnë përdoren si argumente funksioni. Këto vlera u caktohen parametrave, emrat e të cilëve janë renditur në përkufizimin e funksionit. Në trupin e funksionit, shprehjet e aksesit të parametrave kthejnë vlerat e argumenteve përkatëse.

Kur thirret një funksion normal, vlera e kthyer e funksionit bëhet vlera e shprehjes së thirrjes. Nëse funksioni kthehet kur interpretuesi arrin fundin e funksionit, kthehet i padefinuar. 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. Duke pasur parasysh 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) (kthimi a+b;) // Shtoni një metodë në objektin obj obj.metod = func; // Tani mund ta quajmë këtë metodë var result = obj.method(4, 5);

Mënyra më e zakonshme për të thirrur metodat është përdorimi i formës së operatorit me pika të aksesit në pronë, por mund të përdorni gjithashtu formën e kllapave katrore të aksesit në pronë. 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 kthimit të një thirrjeje metode trajtohen saktësisht në të njëjtën mënyrë si një thirrje funksioni normal. 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 (obj në këtë rast) dhe një emër i pronës (metodë). Në shprehje të tilla thirrjeje të metodës, objekti obj bëhet konteksti i thirrjes dhe trupi i funksionit mund t'i referohet këtij objekti duke përdorur këtë fjalë kyçe. Për shembull:

Var obj = ( x: 0, y: 0, // Shto metodë: funksion(a, b) ( this.x = a; this.y = b; ), // Një metodë tjetër shuma: funksion() ( kthe këtë .x + kjo.y)); // Metodat e thirrjes obj.add(15, 4); console.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.

Vini re se kjo është një fjalë kyçe, jo një variabël ose emër pronësie. Sintaksa JavaScript nuk lejon caktimin e vlerave për këtë element.

Argumentet dhe parametrat e funksionit

Në JavaScript, përkufizimet e funksioneve nuk specifikojnë llojet e parametrave dhe kur thirren funksionet, nuk kryhen kontrolle të tipit në vlerat e argumenteve të kaluara. Në fakt, kur thirrni funksione në JavaScript, as numri i argumenteve nuk kontrollohet. Nënseksionet e mëposhtme përshkruajnë se çfarë ndodh nëse numri i argumenteve në një thirrje funksioni është më i vogël ose më i madh se numri i parametrave të deklaruar. Ato demonstrojnë gjithashtu se si mund të kontrolloni në mënyrë eksplicite llojet e argumenteve të funksionit nëse dëshironi 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ë vendosen në të papërcaktuar. 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ë vargun arr dhe kthejeni atë. Nëse nuk është kaluar asnjë argument // arr, krijoni dhe ktheni një funksion të ri të grupit getPropertyNames(obj, /* opsionale */ arr) (nëse (arr === i pacaktuar) arr = ; // Nëse grupi nuk është i përcaktuar, krijoni një të ri një for( vetia var në obj) arr.push(veti); return arr; ) // Ky funksion mund të thirret me 1 ose 2 argumente: var a = getPropertyNames((x:1, y:1)); // Merrni vetitë e objektit në grupin e ri getPropertyNames((z:5),a); // shtoni vetitë e objektit të ri në këtë tastierë të grupit.log(a); // ["x", "y", "z"]

Vini re se gjatë deklarimit të funksioneve, argumentet opsionale duhet të përfundojnë listën e argumenteve në mënyrë që ato të mund të hiqen. Një programues që do t'i shkruajë një thirrje funksionit tuaj nuk do të jetë në gjendje të kalojë argumentin e dytë dhe të heqë të parin: ai do të detyrohet të kalojë në mënyrë eksplicite të papërcaktuar në argumentin e parë. Gjithashtu vini re 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 është më në gjendje të aksesojë drejtpërdrejt vlerat e paemërtuara. Zgjidhja e këtij problemi është dhënë 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ë emrave të tyre.

Supozoni se është përcaktuar një funksion funksion që kërkon një argument të vetëm 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. Gjithashtu, si vargjet e vërteta, argumentet kanë një veçori gjatësi që specifikon numrin e elementeve që përmban. Kjo do të thotë, në trupin e një funksioni funksioni të quajtur me dy argumente, argumentet.gjatësia është 2.

Objekti Arguments mund të përdoret për qëllime të ndryshme. 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, sepse JavaScript nuk do ta bëjë këtë për ju:

Funksioni func(x, y, z) ( // Fillimisht kontrolloni nëse numri i saktë i argumenteve u kalua nëse (arguments.length != 3) ( hidhni gabimin e ri ("Func funksion i thirrur me argumente " + arguments.length + ", por kërkohet 3."); ) // Dhe tani vetë kodi i funksionit... )

Vini re se shpesh nuk është e nevojshme të kontrolloni numrin e argumenteve, si në këtë shembull. Sjellja e paracaktuar e interpretuesit JavaScript është e mirë 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 // ruani më të madhin prej tyre për(var i = 0; im) m = argumentet[i]; // Kthejeni vlerën më të madhe kthe m ;) var më i madhi = maxNumri (1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6); // 10000

Funksionet si ky që mund të marrin një numër arbitrar argumentesh quhen funksione variadike, funksione arity variabël ose funksione varargs. Ky term u ngrit me ardhjen e gjuhës së programimit C.

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

Nuk duhet harruar se argumentet nuk janë në fakt një grup - ai është një objekt Argumenti. Çdo objekt Argumenti ka elementë të numëruar të grupit dhe një veçori gjatësie, por teknikisht nuk është një grup. Është më mirë ta mendojmë atë si një objekt që ka 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 = funksion (x) (nëse (x

Vetitë dhe metodat e funksionit

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

veti gjatësi

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ë kaluara në të vërtetë) me vetinë arguments.callee.length (numrin e argumenteve të pritura) për të përcaktuar nëse funksionit iu kaluan aq argumente sa ai pret. Nëse vlerat nuk përputhen, bëhet një përjashtim. Funksioni check() pasohet nga funksioni i testit func(), i cili demonstron se si të përdoret funksioni check():

// Ky funksion përdor arguments.callee, kështu që // nuk do të funksionojë në modalitetin e rreptë kontrolloni (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, hidhet një përjashtim hidhni gabimin e ri("pritet: " + e pritshme + "; e marrë " + aktuale); ) funksioni func(x, y , z) ( // Kontrollo numrin e argumenteve të pritshme dhe të verifikuara në të vërtetë (argumentet); // Tani ekzekuto pjesën tjetër të funksionit kthim x + y + z; )

pronë prototip

Çdo funksion ka një pronë 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ë një artikull të mëparshëm.

metodat call() dhe apply().

Metodat call() dhe apply() ju lejojnë të thërrisni një funksion në mënyrë indirekte sikur të ishte një metodë e ndonjë objekti tjetër. Argumenti i parë si për call() ashtu edhe për application() ë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 func() (pa argumente) si metodë e objektit obj, mund të përdorni njërën nga metodat call() ose apply():

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

Secila nga mënyrat e thirrjes së saj është e barabartë 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 funksionin një metodë obj obj.m(); // E quaj pa argumente. fshij obj.m; // Hiq metodën e përkohshme.

Në modalitetin e rreptë ECMAScript 5, argumenti i parë për metodat call() dhe apply() bëhet kjo vlerë, edhe nëse është një vlerë e thjeshtë, null ose e papërcaktuar. Në ECMAScript 3 dhe në modalitetin jo strikte, null dhe i papërcaktuar zëvendësohen nga objekti global dhe një vlerë e thjeshtë nga objekti mbështjellës përkatës.

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

Shembulli i mëposhtëm demonstron përdorimin praktik të metodës call():

// Më poshtë janë dy funksione që shfaqin vetitë dhe // vlerat e vetive të një objekti arbitrar. Metoda e shfaqjes // kalohet si një argument i funksionit funksion 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ë ngrihet sepse print1(console.log, obj); // nuk mund t'i thërrasë këto metoda pa një objekt konteksti

metoda bind().

Metoda bind() u shfaq fillimisht 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 thërrisni metodën bind() të func-it dhe ia kaloni një objekt obj, ai do të kthejë një funksion të ri. Thirrja e funksionit të ri (si funksion normal) do të thërrasë funksionin origjinal func si metodë e objektit 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) ( kthej këtë.x + y; ) var obj = (x:1); // Objekt për t'u lidhur me var g = func.bind(obj); // Thirrja e g(x) do të thërrasë obj.func(x)

Ky lloj lidhjeje është i lehtë për t'u zbatuar në ECMAScript 3, siç tregohet më poshtë:

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

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

Artikull në zhvillim e sipër!

Një artikull në të cilin 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 deklaratës kthyese.

Çfarë është një funksion?

Një funksion është disa grup udhëzimesh, e cila mund të emërtohet dhe më pas drejtohu me këtë emër nga kudo në program.

Një shembull klasik i përdorimit të një funksioni. Faqja e internetit përmban kodin JavaScript, ndonjë fragment në të cilin përsëritet disa herë. Për të shmangur këtë, ju mund formatoje 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ë ekzekutimi i udhëzimeve të vendosura në të.

Si të organizoni ekzekutimin e disa detyrave në JavaScript duke përdorur funksione? Për ta bërë këtë, zakonisht bëni diçka të tillë:

  • ndani detyrën në pjesë përbërëse (nëndetyra);
  • nën-detyrat formalizohen përmes funksioneve;
  • zhvilloni kodin kryesor duke përdorur thirrjen e funksioneve të krijuara.

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ë.

Deklarimi dhe thirrja e një funksioni

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

  • shpallje (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, i ndjekur nga një x në kllapa, nëse është e nevojshme. janë renditur parametrat, e ndjekur nga udhëzimet që mbyllur në kllapa kaçurrelë.

// Deklarata e funksionit someName Funksioni someName() ( alert("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 gjithashtu bën dallimin midis funksioneve shprehja e përkufizimit të funksionit dhe shprehja e funksionit me shigjetë .

Përbërja e 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 emri i ndryshores, nuk mund të fillojë me një numër.

Një funksion mund të ketë çdo numër parametrash ose asnjë fare. Kllapat përfshihen në çdo rast. Nëse ka disa parametra, atëherë ato duhet të ndahen nga njëri-tjetri duke përdorur një presje. Parametrat e funksionit arrihen me emrin e tyre.

Set instruksionesh, 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ë kryhet. Për ta ekzekutuar, duhet të thirret. Një funksion 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.Çdo gjë në JavaScript është 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 function someName() ( alert("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 janë vlerat që i kalohen funksionit në fazën e thirrjes së tij. Argumentet ndahen nga njëri-tjetri me presje.

// duke thirrur funksionin sayWelcome me dy argumente që i kalojnë atij sayWelcome("Ivan", "Ivanov"); // një thirrje tjetër në funksionin sayWelcome me dy argumente sayWelcome("Peter", "Petrov");

Parametrat e funksionitështë një mënyrë në JavaScript për t'iu referuar argumenteve brenda një funksioni. Parametrat e funksionit përshkruhen në fazën e deklarimit të tij në kllapa.

Me fjale te tjera parametrat e funksionit 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 gjatë thirrjes së tij. Ju mund t'i qaseni parametrave vetëm brenda këtij funksioni, jashtë tij ato nuk ekzistojnë.

// deklarimi i funksionit sayWelcome, i cili ka funksionin e dy parametrave sayWelcome (userFirstName, userLastName) ( // udhëzim që shfaq vlerat e parametrave "userFirstName" dhe "userLastName" në konsolën e konsolës.log("Welcome, " + Mbiemri 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ë dhe dy parametra:

// duke thirrur funksionin sayWelcome dhe duke i kaluar një argument atij sayWelcome("Peter"); // Mirësevini, Peter i papërcaktuar // duke thirrur funksionin sayWelcome pa i kaluar atij argumente sayWelcome(); // Mirësevini i papërcaktuar i papërcaktuar

Një shembull i një funksioni që thjesht do të shfaqë 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 funksionin outputParam duke i kaluar atij një numër të ndryshëm parametrash outputParam(" Shi" "Borë", "Mjegull"); // Shi; borë; output mjegullParam(17); // 17; i papërcaktuar; dalje e padefinuarParam(24,33); // 24; 33; outputParam(); // 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. Qasja në argumente përmes argumenteve kryhet në të njëjtën mënyrë si tek elementët e një grupi të rregullt, d.m.th. me numrat e tyre serial. Kështu, argumenti - do t'ju lejojë të merrni argumentin e parë, argumentet - argumentin e dytë, e kështu me radhë.

// Deklarata e funksionit sum funksioni sum(num1, num2) ( /* num1 ose argumente - merr vlerën e 1 argumentit num2 ose argumenteve - merr vlerën e 2 argumenteve */ var sum1 = num1 + num2, sum2 = argumentet + argumentet; kthen "Shuma, e përftuar me metodën 1 është " + shuma 1 + "; shuma e përftuar nga metoda 2 është " + shuma 2; ) /* printoni rezultatin e funksionit të shumës në tastierën 7 - argumenti i parë (mund të aksesohet si nga emri num1 dhe sipas argumenteve) 4 - argumenti i dytë (mund të arrihet si nga emri num2 ashtu edhe nga argumentet) */ console.log(sum(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 janë dhënë emrat 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 një emër (me numrin serial). Kjo veçori e gjuhës JavaScript ju lejon të krijoni funksione universale fleksibël.

Përveç marrjes së argumenteve, objekti i argumenteve ju lejon gjithashtu të zbuloni numrin e tyre. Kjo bëhet duke përdorur veçorinë gjatësi.

Përsëriteni mbi argumentet kalohet në një funksion, për shembull, duke përdorur një cikli for ose për...e.

// deklarimi i funksionit sum funksion sum() ( var i = 0; console.log ("Nxjerrja e të gjitha argumenteve duke përdorur ciklin 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ë kryen mbledhjen e të gjitha argumenteve të kaluara në të (numri i tyre nuk dihet paraprakisht):

// Deklarata e funksionit var myCalc = funksion() ( // përsërit 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 ] ;) // ktheje shumën si rezultat ktheje shumën; ) // thirrja e funksionit (dalja në tastierë) console.log(myCalc(4, 20, 17, -6));

Si rezultat, objekti i argumenteve mund të zbatohet në trupin e funksionit:

  • kontrollimi i numrit të argumenteve të miratuara;
  • duke përpunuar çdo numër parametrash.

Përveç vetë funksionit, funksionet e tjera që janë në të gjithashtu kanë qasje në argumentet që i kalohen atij gjatë fazës së 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 paracaktuar e parametrit

Duke filluar me 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 "#009688":

Funksioni setBGColor(color = "#009688") ( document.body.style.backgroundColor = color; ) 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(ngjyra) (ngjyra = ngjyra !== e papërcaktuar ? ngjyra: "#009688"; // vendos ngjyrën në vlerën e saj të paracaktuar të "#009688" document.body.style.backgroundColor = ngjyra; )

Parametrat e mbetur

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

// ...numrat janë parametrat e mbetur, të cilët mund të arrihen në këtë rast me emrin nums funksion doMath(mathAction, ...nums) ( var rezultat = 0; nums.forEach(funksion(vlera) ( 'ndërprerës ( mathAction) (rasti "shuma": rezultat += vlerë; pushim; rasti "sumCube": rezultat += vlerë**3; pushim; rast "shumë katror": rezultat += vlerë**2; thyerje; i padëgjuar: rezultat = 0 ; ) ) ) kthen rezultatin; ) console.log(doMath("sum", 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)

deklaratë kthimi

Deklarata e kthimit synon të kthejë vlerën ose rezultatin e 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 në JavaScript kthen gjithmonë një rezultat, pavarësisht nëse deklarata e kthimit përdoret apo jo.

// funksioni i kthimit sayWelcome (userFirstName, userLastName) ( if (!userFirstName) || (!userLastName)) kthen "Mirë se erdhe, përdorues anonim"; përndryshe kthe "Mirë se erdhe, " + userLastName + " " + userFirstName ; deklarata variabël person var person; // cakto rezultatin e funksionit sayWelcome variablit person person = sayWelcome("Ivan","Ivanov"); // printoni vlerën e ndryshores në konsolën e konsolës.log(person); //Udhëzim që do të nxjerrë në konsolë rezultatin e funksionit sayWelcome console.log(sayWelcome("Peter","Petrov")); //Udhëzim që do të nxjerrë në konsolë rezultatin e funksionit sayWelcome console.log(sayWelcome("Sidorov")); JavaScript - Funksioni me Validimin e Parametrave

Një funksion në JavaScript kthen gjithmonë një rezultat si rezultat i ekzekutimit të tij, 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 nuk ktheni asgjë konsol .log(thoniMirë se vini ("Ivan", "Ivanov")); // 2. një funksion që përmban një deklaratë kthimi pa një funksion vlere sayDay (ditë) ( ditë = "Sot, " + ditë; kthe; //kjo deklaratë nuk do të ekzekutohet sepse vjen pas deklaratës së kthimit console.log(day ) ;) // provoni të merrni rezultatin e funksionit që përmban deklaratën e kthimit pa një vlerë konsol.log(sayDay("21 shkurt 2016")); JavaScript - Merrni vlerë nga një funksion që nuk kthen asgjë

I njëjti rezultat do të merret nëse një vlerë e kthimit nuk është specifikuar 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 sipas llojit dhe numrit të argumenteve. Secili funksion ka logjikën e vet të programimit. Mbingarkimi i funksionit përdoret në mënyrë që veprime të ngjashme të mund të kryhen duke përdorur të njëjtin emër funksioni.

Gjuha JavaScript nuk mbështet mbingarkimin e funksionit në mënyrën se si zbatohet, për shembull, në gjuhë të ngjashme me C. ato. në JavaScript, nuk mund të krijoni funksione të shumta me të njëjtin emër që janë në të njëjtin 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ër të kontrolluar numrin e argumenteve të kaluara në një funksion, përdorni vetinë e gjatësisë së argumenteve të objektit.
  • Për të gjetur llojin e vlerës së argumentit të kaluar, përdorni operatorët typeof ose instanceof.
  • Për të punuar me një numër të ndryshueshëm argumentesh, përdorni objektin e argumenteve.
  • Duke filluar me ECMAScript6, mund të specifikoni 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 është specifikuar kur thirret if (elementet=== të papërcaktuara) ( //pastaj vendoseni vlerën e tij në "div" elementet = "div "; ) // merrni të gjithë elementët elementë = $(elementë); // lakoni të gjithë elementët dhe vendosini ato në elementët e specifikuar të ngjyrës së sfondit. secili(funksion()( $(this). css ("sfondi -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 Është vendosur 2 parametër, 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, ne 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,elements = "div") ( //merr të gjithë elementët e elementeve = $(elemente); / /përsërisni të gjithë elementët dhe vendosni ngjyrën e specifikuar të sfondit për elementët e tyre.each(funksion()( $(this).css("background-color",bgColor); )); //thirrni funksionin setBgColor, duke specifikuar një parametër setBgColor ("jeshile"); //thirrni funksionin setBgColor, duke specifikuar 2 parametra setBgColor("#ff0000","button");

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

// funksioni i përshkrimit të funksionit countCal(seks, lartësi) ( // 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 if (argumentet) (rezultati *= argumentet; ) console.log ("Numri i kalorive për jetën normale: " + rezultat); ) else (consol.log ("Parametrat e pavlefshëm"); ) ) / * thirrja e funksionit dhe kalimi i tij 2 argumente (1 - "man", mund të aksesohet me emrin seksi dhe argumentet; 2 - vlera 185, mund të arrihet me emrin seks dhe argumentet) */ countCal("man", 185); /* duke thirrur funksionin dhe duke i kaluar 3 parametra, megjithëse vetëm 2 janë të pranishëm 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);

rekursion

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

Një funksion zakonisht thirret në varësi të mënyrës se si deklarohet me emër ose nga një variabël që përmban një referencë për këtë funksion.

Funksioni fakt(n) ( if (n === 1) ( return 1; ) return fact(n-1) * n; ) console.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ër më tepër, nuk funksionon fare në mënyrë strikte.

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ë ose një objekti tjetër.

Për shembull, për të thirrur sinjalizimin e funksionit (metodës) së integruar, 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 sinjalizimin e funksionit ("Disa tekst"); JavaScript - Thirrja e funksionit të alarmit

Funksionet janë një nga blloqet themelore të ndërtimit në JavaScript. Një funksion është një procedurë JavaScript - një grup deklaratash që kryen një detyrë ose llogarit një vlerë. Për të përdorur një funksion, duhet ta përcaktoni atë diku në sferën nga e cila dëshironi ta thërrisni.

A metodëështë një funksion që është një veti e një objekti. Lexoni më shumë rreth objekteve dhe metodave në Puna me objekte.

Funksionet e thirrjes

Përcaktimi i një funksioni nuk e ekzekuton atë. Përcaktimi i funksionit thjesht emërton funksionin dhe specifikon se çfarë duhet bërë kur funksioni thirret. duke thirrur funksioni në fakt kryen veprimet e specifikuara me parametrat e treguar. Për shembull, nëse përcaktoni funksionin katror , mund ta quani si më poshtë:

Sheshi (5);

Deklarata e mëparshme thërret funksionin me një argument prej 5. Funksioni ekzekuton deklaratat e tij dhe kthen vlerën 25.

Funksionet duhet të jenë në shtrirje kur thirren, por deklarata e funksionit mund të ngrihet (shfaqet poshtë thirrjes në kod), si në këtë shembull:

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

Shtrirja e një funksioni është funksioni në të cilin ai deklarohet, ose i gjithë programi nëse deklarohet në nivelin më të lartë.

Shënim: Kjo funksionon vetëm kur përcaktoni funksionin duke përdorur sintaksën e mësipërme (d.m.th. funksioni funcName()()). Kodi më poshtë nuk do të funksionojë. Kjo do të thotë, ngritja e funksionit funksionon vetëm me deklarimin e funksionit dhe jo me shprehjen e funksionit.

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

Argumentet e një funksioni nuk kufizohen në vargje dhe numra. Ju mund të kaloni objekte të tëra në një funksion. Funksioni show_props() (i përcaktuar në ) është një shembull i një funksioni që merr një objekt si argument.

Një funksion mund të thërrasë veten. Për shembull, këtu është një funksion që llogarit faktorët në mënyrë rekursive:

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

Më pas mund të llogaritni faktorialet e një deri në pesë si më poshtë:

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 funksionet. Ka shpesh raste kur një funksion duhet të thirret në mënyrë dinamike, ose numri i argumenteve për një funksion ndryshon, ose në të cilat konteksti i thirrjes së funksionit duhet të vendoset në një objekt specifik të përcaktuar në kohën e ekzekutimit. Rezulton se funksionet janë, vetë, objekte, dhe këto objekte nga ana e tyre kanë metoda (shih objektin Funksioni). Një nga këto, metoda aplikoni(), mund të përdoret për të arritur këtë qëllim.

fushëveprimi i funksionit

Variablat e përcaktuar brenda një funksioni nuk mund të aksesohen nga askund jashtë funksionit, sepse ndryshorja përcaktohet vetëm në fushëveprimin e funksionit. Sidoqoftë, një funksion mund të aksesojë të gjitha variablat dhe funksionet e përcaktuara brenda fushës në të cilën është përcaktuar. Me fjalë të tjera, një funksion i përcaktuar në shtrirjen globale mund të aksesojë të gjitha variablat e përcaktuara në shtrirjen globale. Një funksion i përcaktuar brenda një funksioni tjetër mund të aksesojë gjithashtu të gjitha ndryshoret e përcaktuara në funksionin e tij prind dhe çdo ndryshore tjetër në të cilën funksioni prind ka akses.

// Variablat e mëposhtëm janë përcaktuar në shtrirjen globale var num1 = 20, num2 = 3, emri = "Chamahk"; // Ky funksion është përcaktuar në funksionin global të shtrirjes multiply() ( return num1 * num2; ) multiply(); // Kthen 60 // Funksioni i shembullit të një funksioni të ndërthurur getScore() ( var num1 = 2, num2 = 3; funksioni add() ( kthen emrin + " shënuar " + (num1 + num2); ) kthe add (); ) getScore (); // Kthehet "Çamahk shënoi 5"

Fushëveprimi dhe grupi i funksioneve

rekursion

Një funksion mund t'i referohet dhe të thërrasë veten. Ekzistojnë tre mënyra që një funksion t'i referohet vetes:

  1. emri i funksionit
  2. një variabël brenda fushës që i referohet funksionit

Për shembull, merrni parasysh përkufizimin e mëposhtëm të funksionit:

Var foo = funksion bar() ( // deklaratat shkojnë këtu );

Brenda trupit të funksionit, sa më poshtë janë të gjitha ekuivalente:

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

Një funksion që thërret veten quhet a funksioni rekurziv. Në disa mënyra, rekursioni është analog me një lak. Të dy ekzekutojnë të njëjtin kod disa herë, dhe të dy kërkojnë një kusht (për të shmangur një lak të pafund, ose më mirë, rekursion të pafund në këtë rast). Për shembull, cikli i mëposhtëm:

Var x = 0; ndërsa (x< 10) { // "x < 10" is the loop condition // do stuff x++; }

mund të konvertohet në një funksion rekurziv dhe një thirrje për atë funksion:

Funksioni loop(x) ( nëse (x >= 10) // "x >= 10" është kushti i daljes (ekuivalent me "!(x< 10)") return; // do stuff loop(x + 1); // the recursive call } loop(0);

Megjithatë, disa algoritme nuk mund të jenë unaza të thjeshta përsëritëse. Për shembull, marrja e të gjitha nyjeve të një strukture peme (p.sh. DOM) bëhet më lehtë duke përdorur rekursionin:

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

Krahasuar me qarkun e funksionit, çdo thirrje rekursive në vetvete bën shumë thirrje rekursive këtu.

Është e mundur të konvertohet çdo algoritëm rekurziv në një jo-rekurziv, por shpesh logjika është shumë më komplekse dhe për ta bërë këtë kërkon përdorimin e një rafte. Në fakt, vetë rekursioni përdor një pirg: pirg funksioni.

Sjellja e ngjashme me pirg 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

Mund të futni një funksion brenda një funksioni. Funksioni i ndërthurur (i brendshëm) është privat ndaj funksionit të tij që përmban (i jashtëm). Ai gjithashtu formon një mbyllje. Një mbyllje është një shprehje (zakonisht një funksion) që mund të ketë variabla të lira së bashku me një mjedis që lidh ato variabla (që "mbyll" shprehjen).

Meqenëse një funksion i ndërthurur është një mbyllje, kjo do të thotë që një funksion i mbivendosur mund të "trashëgojë" argumentet dhe variablat e funksionit që përmban. Me fjalë të tjera, funksioni i brendshëm përmban shtrirjen e funksionit të jashtëm.

  • Funksioni i brendshëm mund të arrihet vetëm nga deklaratat në funksionin e jashtëm.
  • Funksioni i brendshëm formon një mbyllje: funksioni i brendshëm 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ë brendshëm.

Shembulli i mëposhtëm tregon funksionet e ndërlidhura:

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

Meqenëse funksioni i brendshëm formon një mbyllje, mund të thërrisni funksionin e jashtëm dhe të specifikoni argumente për funksionin e jashtëm dhe të brendshëm:

Funksioni jashtë(x) (funksioni brenda(y) (kthimi x + y; ) kthimi brenda; ) fn_brenda = jashtë (3); // Mendoni për këtë si: më jepni një funksion që shton 3 në çdo gjë që jepni // 'it result = fn_inside(5); // kthen 8 rezultat1 = jashtë (3) (5); // kthen 8

Ruajtja e variablave

Vini re se si x ruhet kur kthehet brenda. Një mbyllje duhet të ruajë argumentet dhe variablat në të gjitha sferat që i referohet. Meqenëse çdo thirrje ofron argumente potencialisht të ndryshme, krijohet një mbyllje e re për çdo thirrje për jashtë. Kujtesa mund të lirohet vetëm kur pjesa e brendshme e kthyer nuk është më e aksesueshme.

Kjo nuk është e ndryshme nga ruajtja e referencave në objekte të tjera, por shpesh është më pak e dukshme sepse nuk i vendos referencat drejtpërdrejt dhe nuk mund t'i kontrollojë ato.

Funksione me shumë fole

Funksionet mund të jenë të mbivendosura të shumëfishta, d.m.th. një funksion (A) që përmban një funksion (B) që përmban një funksion (C). Të dy funksionet B dhe C formojnë mbyllje këtu, kështu që B mund të hyjë në A dhe C mund të aksesojë B. Përveç kësaj, meqenëse C mund të aksesojë B e cila mund të aksesojë A, C mund të aksesojë gjithashtu A. Kështu, mbylljet mund të përmbajnë fusha të shumta; ato përmbajnë në mënyrë rekursive shtrirjen e funksioneve që e përmbajnë atë. Kjo quhet zinxhiri i fushëveprimit. (Përse quhet "lidhja me zinxhir" do të shpjegohet më vonë.)

Merrni parasysh shembullin e mëposhtëm:

Funksioni A(x) (funksioni B(y) ( funksioni C(z) ( konsol. log(x + y + z); ) C(3); ) B(2); ) A(1); // regjistrat 6 (1 + 2 + 3)

Në këtë shembull, C akseson B "s y dhe A "s x. Kjo mund të bëhet sepse:

  1. B formon një mbyllje duke përfshirë A , d.m.th. B mund të aksesojë argumentet dhe variablat e A-së.
  2. C formon një mbyllje duke përfshirë B.
  3. Për shkak se mbyllja e B përfshin A , mbyllja e C përfshin A , C mund të hyjë në të dy B dhe Argumentet dhe variablat A "s. Me fjalë të tjera, C zinxhirë qëllimet e B dhe A në atë rend.

E kundërta, megjithatë, nuk është e vërtetë. A nuk mund t'i qaset C-së, sepse A-ja nuk mund të aksesojë ndonjë argument ose variabël të B, të cilit C është një variabël. Kështu, C mbetet private vetëm për B.

Konfliktet e emrave

Kur dy argumente ose variabla në qëllimet e një mbylljeje kanë të njëjtin emër, ekziston një konflikti i emrit. Më shumë sfera të brendshme kanë përparësi, kështu që shtrirja më e brendshme merr përparësinë më të lartë, ndërsa shtrirja më e jashtme merr përparësinë më të ulët. Ky është zinxhiri i shtrirjes. E para në zinxhir është shtrirja më e brendshme, dhe e fundit është shtrirja më e jashtme. 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

Konflikti i emrit ndodh në deklaratën kthyese x dhe është ndërmjet parametrit "s" brenda "x" dhe ndryshores "s" jashtë x. Zinxhiri i shtrirjes këtu është (brenda, jashtë, objekti global). Prandaj, brenda "s x" ka përparësi ndaj "s x" nga jashtë, dhe 20 (brenda "s x) kthehet në vend të 10 (jashtë "s x).

Mbylljet

Mbylljet janë një nga veçoritë më të fuqishme të JavaScript. JavaScript lejon futjen e funksioneve dhe i jep funksionit të brendshëm akses të plotë në të gjitha variablat dhe funksionet e përcaktuara brenda funksionit të jashtëm (dhe të gjitha variablat dhe funksionet e tjera në të cilat funksioni i jashtëm ka akses). Megjithatë, funksioni i jashtëm nuk ka akses në variablat dhe funksionet e përcaktuara brenda funksionit të brendshëm. Kjo siguron një lloj kapsulimi për variablat e funksionit të brendshëm. Gjithashtu, meqenëse funksioni i brendshëm ka akses në shtrirjen e funksionit të jashtëm, variablat dhe funksionet e përcaktuara në funksionin e jashtëm do të jetojnë më gjatë se kohëzgjatja e ekzekutimit të funksionit të jashtëm, nëse funksioni i brendshëm arrin të mbijetojë përtej jetës së funksionit të jashtëm. funksionin. Një mbyllje krijohet kur funksioni i brendshëm vihet disi i disponueshëm për çdo qëllim jashtë funksionit të jashtëm.

Var pet = funksion(emri) ( // Funksioni i jashtëm përcakton një variabël të quajtur "emri" var getName = funksion() ( emri i kthimit; // Funksioni i brendshëm ka akses në ndryshoren "emër" të //funksionit të jashtëm) ktheje getName; // Ktheje funksionin e brendshëm, duke e ekspozuar atë në sferat e jashtme ) myPet = pet ("Vivie"); kafsha ime shtepiake(); // Kthen "Vivie"

Mund të jetë shumë më kompleks se kodi i mësipërm. Një objekt që përmban metoda për manipulimin e ndryshoreve të brendshme të funksionit të jashtëm mund të kthehet.

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

Në kodin e mësipërm, ndryshorja e emrit të funksionit të jashtëm është e aksesueshme për funksionet e brendshme dhe nuk ka asnjë mënyrë tjetër për të hyrë në ndryshoret e brendshme përveçse përmes funksioneve të brendshme. Variablat e brendshëm të funksioneve të brendshme veprojnë si depo të sigurta për argumentet dhe variablat e jashtëm. Ata mbajnë të dhëna "të vazhdueshme" dhe "të kapsuluara" për funksionet e brendshme për të punuar. Funksionet as që duhet t'i caktohen një ndryshoreje, ose të kenë një emër.

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

Megjithatë, ka një numër grackash për t'u kujdesur kur përdorni mbyllje. Nëse një funksion i mbyllur përcakton një ndryshore me të njëjtin emër si emri i një ndryshoreje në shtrirjen e jashtme, nuk ka asnjë mënyrë për t'iu referuar ndryshores në shtrirjen e jashtme përsëri.

Var createPet = funksion(emri) ( // Funksioni i jashtëm përcakton një variabël të quajtur "emri". return (setName: funksion(emri) ( // Funksioni i mbyllur gjithashtu përcakton një variabël 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 e një funksioni mbahen në një objekt të ngjashëm me grupin. Brenda një funksioni, ju mund t'i adresoni argumentet e kaluara në të si më poshtë:

Argumentet[i]

ku i është numri rendor i argumentit, duke filluar nga zero. Pra, argumenti i parë i kaluar në një funksion do të ishte argumentet. Numri i përgjithshëm i argumenteve tregohet me argumente.gjatësia .

Duke përdorur objektin e argumenteve, mund të thërrisni një funksion me më shumë argumente sesa është deklaruar zyrtarisht për të pranuar. Kjo është shpesh e dobishme nëse nuk e dini paraprakisht se sa argumente do t'i kalojnë funksionit.Mund të përdorni argumentet.length për të përcaktuar numrin e argumenteve të kaluara në të vërtetë në funksion dhe më pas të përdorni çdo argument duke përdorur objektin e argumenteve.

Për shembull, merrni parasysh një funksion që bashkon disa vargje. Argumenti i vetëm formal për funksionin është një varg që specifikon karakteret që ndajnë artikujt për t'u bashkuar. Funksioni është përcaktuar si më poshtë:

Funksioni myConcat(ndarës) (var rezultat = ""; // inicializoj listën var i; // përsërit 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 bashkon çdo argument në një varg "listë":

// 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(". ", "sherebelë", "borzilok", "rigon", "piper", "majdanoz");

Shënim: Variabla e argumenteve është "array-like", por jo një grup. Ai është i ngjashëm me grupin në atë që ka një indeks të numëruar dhe një veçori gjatësi. Megjithatë, ai nuk i posedon të gjitha metodat e manipulimit të grupeve.

Dy faktorë ndikuan në prezantimin e funksioneve të shigjetës: funksionet më të shkurtra dhe jo-detyruese e kësaj.

Funksione më të shkurtra

Në disa modele funksionale, funksionet më të shkurtra janë të mirëseardhura. krahaso:

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

Jo veçuar këtë

Derisa të funksionojë 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ë thirrjet e funksionit, objekti bazë nëse funksioni thirret si "metodë objekti", etj.). Kjo ka rezultuar të jetë më pak se ideale me një stil programimi të orientuar nga objekti.

Funksioni Person() ( // Konstruktori Person() e përcakton "këtë" si vetë. this.age = 0; setInterval(funksioni growUp() ( // Në modalitetin jostrikt, funksioni growUp() përcakton "këtë" // si objekti global, 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 në këtë një ndryshoreje që mund të mbyllet.

Funksioni Person() ( var self = this; // Disa zgjedhin 'that' në vend të 'vet'. // Zgjidhni një dhe jini të qëndrueshëm. self.age = 0; setInterval(function growUp() ( // Thirrja i referohet ndryshorja `self` e së cilës // vlera është objekti i pritur.self.age++; ), 1000); )

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

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

Kjo do të thotë, funksioni, së pari, nuk ka një 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ë njoftim i tillë shkaktoi hutim dhe keqkuptim se si funksionon dhe pse të shkruaj fare kështu.

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

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

Dhe këtu kemi ardhur 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. Mund ta shkruani numrin 5 në variablin e rezultatit, apo jo? 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 nuk duket më diçka e pabesueshme.

Fakti tjetër interesant është një vazhdim logjik i të parit. Pasi të vendosim të dhënat në një variabël, ne mund t'i kalojmë të dhënat në një variabël tjetër duke përdorur emrin e kësaj ndryshore:

Var a = 5; var b = a; alarmi (b); //daljet 5

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

Var add = funksion(arg1, arg2) ( var sum = arg1 + arg2; kthim shuma; ) var calcSum = add; alarm (calcSum (5, 6)); //daljet 11

A keni filluar të hamendësoni? Meqenëse një funksion është si një ndryshore, ne mund ta "shpërndajmë" atë me caktim të zakonshëm në variabla të tjerë, duke i kthyer ato gjithashtu në funksione. Tani calcSum mund të shtojë edhe dy numra. Megjithatë, kodi

VarcalcSum = 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 caktuam vetë funksionin, por rezultatin e ekzekutimit të tij (kllapat tregojnë se funksioni duhet të ekzekutohet, jo të caktohet).

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

Var calcFact = funksioni fakt(val) (nëse (val == 1) ? val: val * fakt(val - 1); // llogarit faktorialin duke përdorur rekursionin) alert(calcFact(4)); //daljet 24

Këtu, duke i caktuar funksionin një ndryshoreje, i dhamë 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, veçori interesante! Por cili është avantazhi i të bërit këtë? A ka situata ku është e pashmangshme, ose të paktën më e përshtatshme se një deklaratë e rregullt?". Unë nuk do të marr përsipër të pohoj se ka situata ku është e pamundur të bëhet pa një qasje të tillë, 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 = (date.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 vendosnim të shkonim në rrugën "klasike", atëherë do të duhej të shkruanim tre funksione të veçanta dhe më pas t'i thërrasim në kushtin e testimit të kohës:

Funksioni GoodMorning() ( alert("Mirëmëngjes!"); ) funksion goodPasdite() ( alert("Mirëdita!"); ) funksion goodEvning() ( alarm("Mirëmbrëma!"); ) var data = data e re (); (data.getHours()< 12) ? goodMorning() : (date.getHours() < 18) ? goodAfternoon() : goodEvning();

Kodi është rritur ndjeshëm vizualisht, edhe pse kemi përdorur formën e shkurtër të deklaratës së kushtëzuar. Nëse supozojmë se skedari përmban funksione vërtet të rëndësishme që kryejnë llogaritjet, atëherë ndotja e listës me minifunksione të tilla që nuk kanë logjikë të rëndësishme dhe që me shumë mundësi përdoren vetëm një herë, nuk është një ide e mirë. Për më tepër, ne jemi të detyruar t'i japim çdo funksioni një emër unik dhe ta specifikojmë atë gjatë thirrjes. 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) ( return a + b; ) var calcSum = add; calcSum (5, 5);

Tashmë e pamundur. Prandaj, në shembullin tonë, nëse ende duhet të përshëndesim të ftuarin 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ë mjaftojë të shkruani vetëm hello(); 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 ta gjeni menjëherë përdorimin e këtyre veçorive në projektet tuaja, të paktën do ta dini se ekzistojnë veçori të tilla. Dhe kur të shfaqet një mundësi vërtet e mirë, mund të zvogëloni sasinë e kodit dhe të shmangni konfuzionet dhe gabimet e panevojshme.!

Ky artikull përshkruan veçoritë e Javascript në nivel gjuhësor: krijimi, opsionet, 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++ alert(funcObj.test) ) func.test = 1 func() func()

Në fillim të punës, çdo funksion krijon një variabël argumentesh brenda vetes dhe cakton argumente.callee një referencë për vete. Pra arguments.callee.test është një veti e func.test, d.m.th., një test variabël statik.

Në shembull, ishte e pamundur të bëhej një detyrë:

Vartest = argumente.callee.test test++

sepse në këtë rast operacioni ++ do të funksiononte 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ë), më shumë për këtë më vonë në seksionin mbi parametrat.

Fushëveprimi

Çdo funksion, më saktë, edhe çdo nisje funksioni, përcakton shtrirjen e vet individuale.

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

Ndryshe nga disa gjuhë, blloqet nuk përcaktojnë një fushë të veçantë. Nuk ka rëndësi nëse ndryshorja përcaktohet brenda bllokut apo jashtë tij. Pra, këto dy fragmente janë krejtësisht ekuivalente:

Një ndryshore e përcaktuar nëpërmjet var është e dukshme kudo në fushëveprimin, madje edhe para deklaratës var. Për shembull, le të bëjmë një funksion që do të ndryshojë variablin, var për të cilin është më poshtë.

Për shembull:

Funksioni a() (z = 5 // do të ndryshojë z në nivel lokal.. // .. sepse z deklarohet nëpërmjet var var z) // fshij z testin // pastroj za() globale vetëm në rast alarmi (window.z) // => e papërcaktuar pasi 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 e distancës me një shpejtësi uniforme të shpejtësisë.

Herën e parë që funksioni ekzekutohet me argumente distance=10 , speed=pacaktuar . Zakonisht kjo situatë, nëse mbështetet nga funksioni, siguron një vlerë të paracaktuar:

// nëse shpejtësia është 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 që kalon në true).

Prandaj, përdoret për të vendosur vlerat e paracaktuara. Në thirrjen tonë, shpejtësia do të vlerësohet si e pacaktuar || 10 = 10 .

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

Lëshimi i dytë është standard.

Drejtimi i tretë specifikon disa argumente shtesë. Funksioni nuk funksionon 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 kemi rezultatin e pjesëtimit të papërcaktuar/10 = NaN (Jo-Numër, ka ndodhur një gabim).

Puna me një numër të pacaktuar parametrash

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

  1. Thirrni argumente, duke filluar nga zero
  2. Gjatësia në vetinë gjatësi
  3. Referenca për vetë funksionin në vetinë e thirrësit

Për shembull,

Funksioni func() ( for(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, të tilla 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.call(argumentet) // .. tani args është një grup i vërtetë 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)

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 një funksion funksioni, e zbaton atë në secilin element të grupit arr dhe kthen grupin që rezulton:

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

Shembull përdorimi:

Harta(drejtuar, ) // =

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

// funksioni anonim trefishon numrat harta(funksioni (a) (kthimi a*3 ) , ) // =

Kolapsimi i parametrave në një objekt

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

Për shembull:

// vetëm një pjesë e argumenteve mund të specifikohet // nuk specifikohet - llogaritet ose merret sipas funksionit të paracaktuar ndryshimi i madhësisë (toWidth, toHeight, saveProportions, animate) ( // vlerat e paracaktuara saveProportions = saveProportions || animate e vërtetë = animuar || e vërtetë deri në Lartësi = në Lartësi | | ...)

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ë kuptueshëm, ata përdorin diçka si "argumentet e fjalëve kyçe" që ekzistojnë në Python dhe Ruby. Për ta bërë këtë, shumë parametra paketohen në një objekt të vetëm:

Ndryshimi i përmasave të 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 thjeshtë:

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

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

Përveç kësaj, është më i përshtatshëm për të bërë sekuenca thirrjesh me një objekt si:

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

Artikujt kryesorë të lidhur