Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • Windows Phone
  • Javascript folosind o funcție declarată anterior într-o altă funcție. Funcții

Javascript folosind o funcție declarată anterior într-o altă funcție. Funcții

Articol în curs de dezvoltare!

Un articol în care luăm în considerare ce este o funcție, precum și versiunea tradițională (clasică) a lucrului cu ea. În plus, vom analiza care sunt argumentele (parametrii) funcției și instrucțiunii return.

Ce este o funcție?

O funcție este unele set de instructiuni, care poate fi numit și apoi adresați-i cu acest nume de oriunde în program.

Un exemplu clasic de utilizare a unei funcții. Pagina web conține cod JavaScript, oarecare fragment în care se repetă de mai multe ori. Pentru a evita acest lucru, puteți formatați acest fragment ca funcție, dar apoi sună-lîn locurile potrivite din cod după denumirea acestei funcţii. Apelarea acestei funcții va însemna executarea instructiunilor situat în el.

Cum se organizează execuția unei sarcini în JavaScript folosind funcții? Pentru a face acest lucru, de obicei faceți ceva de genul acesta:

  • împărțiți sarcina în părți componente (subsarcini);
  • subsarcinile sunt formalizate prin funcții;
  • dezvolta codul principal folosind apelul functiilor create.

Ca urmare, un astfel de program devine mai structurat. Este mai ușor să faceți diverse modificări și să adăugați noi funcții.

Declararea și apelarea unei funcții

Operațiile cu funcții în JavaScript pot fi împărțite în 2 pași:

  • anunț (creare) funcții.
  • apel (execuție) această funcție.

Declarație de funcție. Crearea unei funcții în JavaScript începe prin scrierea cuvântului cheie al funcției, urmat de numele funcției, urmat de un x între paranteze, dacă este necesar. parametrii sunt listați, urmată de instrucțiuni care cuprinse între paranteze.

// declarația funcției someName function someName() ( alert("Ați apelat funcția someName!"); ) JavaScript - Sintaxa de declarare a funcției

Funcțiile de acest fel în JavaScript sunt numite declarație de funcție. Pe lângă acest tip, JavaScript face distincție între funcții expresie de definire a funcțieiși expresia funcției săgeată.

Compoziția numelui funcției urmează aceleași reguli ca și numele variabilei. Acestea. poate conține litere, cifre (0-9), semne „$” și „_”. Este recomandat să folosiți doar litere din alfabetul englez (a-z, A-Z) ca litere. Un nume de funcție, ca un nume de variabilă, nu poate începe cu un număr.

O funcție poate avea orice număr de parametri sau deloc. Parantezele sunt incluse în orice caz. Dacă există mai mulți parametri, atunci aceștia trebuie separați unul de celălalt folosind o virgulă. Parametrii funcției sunt accesați după numele lor.

Set de instructiuni, cuprins între acolade, este codul funcției care va fi executat atunci când este apelat.

Apel de funcție. Funcție declarată de propria ei nu vor fi efectuate. Pentru a-l rula, trebuie apelat. O funcție este apelată prin specificarea numelui și a două paranteze. Argumentele sunt date între paranteze, dacă este necesar.

// apelează funcția dată în exemplul anterior someName(); JavaScript - Sintaxă a apelurilor de funcție

Este o funcție din JavaScript un obiect?

Funcțiile din JavaScript sunt obiecte. Totul în JavaScript este un obiect, cu excepția celor șase tipuri de date primitive. Și dacă funcția este un obiect, atunci o referință la aceasta poate fi stocată într-o variabilă.

// declarație funcție someName function someName() ( alert("Ați sunat funcția someName!"); ) var referință = someName;

După aceea, puteți apela funcția astfel:

Referinţă();

Parametrii și argumentele funcției

Argumente ale funcției sunt valorile care sunt transmise funcției în etapa apelării acesteia. Argumentele sunt separate unele de altele prin virgulă.

// apelarea funcției sayWelcome cu două argumente transmise sayWelcome("Ivan", "Ivanov"); // încă un apel la funcția sayWelcome cu două argumente sayWelcome("Peter", "Petrov");

Parametrii funcției este o modalitate în JavaScript de a se referi la argumente dintr-o funcție. Parametrii funcției sunt descriși în etapa de declarare a acesteia între paranteze.

Cu alte cuvinte parametrii funcției sunt variabile locale care sunt create automat în etapa de pornire a funcției. Ca valori, parametrii primesc argumentele corespunzătoare transmise funcției în timpul apelării acesteia. Puteti accesa parametrii doar in interiorul acestei functii, in afara ei nu exista.

// declarația funcției sayWelcome, care are doi parametri funcție sayWelcome (userFirstName, userLastName) ( // instrucțiune care afișează valorile parametrilor „userFirstName” și „userLastName” în consola console.log(„Welcome,” + userLastName + " " + userFirstName ); )

În JavaScript, la apelarea unei funcții numărul de argumente nu trebuie să fie același cu numărul de parametri. Parametrii care nu au fost setați la o valoare atunci când sunt apelați vor fi nedefiniți.

De exemplu, să apelăm funcția din exemplul de mai sus, fără a specifica unul și doi parametri:

// se apelează funcția sayWelcome și îi trece un argument sayWelcome("Peter"); // Bun venit, Peter nedefinit // apelând funcția sayWelcome fără a-i transmite argumente sayWelcome(); // Bun venit undefined undefined

Un exemplu de funcție care va afișa pur și simplu argumentele transmise în consola browserului:

// declararea funcției funcția outputParam(param1, param2, param3) ( console.log(param1 + "; " + param2 + "; " + param3); ) // apelează funcția outputParam trecându-i un număr diferit de parametri outputParam(" Ploaie" ,"Zăpadă", "Ceață"); // Ploaie; Zăpadă; mist outputParam(17); // 17; nedefinit; nedefinit outputParam(24,33); // 24; 33; nedefinit outputParam(); // nedefinit; nedefinit; nedefinit

Un alt mod de a face referire la argumente dintr-o funcție este de a folosi obiectul argumente speciale. Accesul la argumente prin argumente se realizează în același mod ca și la elementele unui tablou obișnuit, i.e. după numerele lor de serie. Astfel, argument - vă va permite să obțineți primul argument, argumente - al doilea argument și așa mai departe.

// declarație funcție sum function sum(num1, num2) ( /* num1 sau argumente - obține valoarea unui argument num2 sau argumente - obține valoarea a 2 argumente */ var sum1 = num1 + num2, sum2 = argumente + argumente; returnează "Suma, obținută prin metoda 1 este " + sum1 + "; suma obținută prin metoda 2 este " + sum2; ) /* imprimă rezultatul funcției sum în consola 7 - primul argument (poate fi accesat atât prin nume num1 și prin argumente) 4 - al doilea argument (se poate accesa atât prin numele num2 cât și prin argumente) */ console.log(sum(7,4));

Principala diferență dintre aceste metode este că prima dintre ele vă permite să accesați doar acele argumente cărora li sa dat nume în etapa declarării funcției. A doua metodă vă permite să obțineți valoarea oricărui argument, chiar dacă acesta nu are un nume (după numărul de serie). Această caracteristică a limbajului JavaScript vă permite să creați funcții universale flexibile.

Pe lângă primirea argumentelor, obiectul arguments vă permite și să aflați numărul acestora. Acest lucru se face folosind proprietatea lungime.

Iterați peste argumente transmis la o funcție, de exemplu, folosind o buclă for sau for...of.

// declararea funcției sum funcția sum() ( var i = 0; console.log("Ieșiți toate argumentele folosind bucla for"); for (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);

O funcție care imprimă pe consolă toate argumentele transmise acesteia și numărul lor:

// funcția de declarare a funcției myFunction () ( var i; console.log("Numărul de parametri trecuți = " + arguments.length); // iterează peste toți parametrii folosind bucla for for (i = 0; i< arguments.length; i++) { console.log(i + " параметр = " + arguments[i]); } } // вызовы функции myFunction myFunction(3, 7, 27, "JavaScript"); myFunction(); myFunction("Яблоки", "Груши", "Апельсины");

O funcție care efectuează adăugarea tuturor argumentelor transmise acesteia (numărul acestora nu este cunoscut în prealabil):

// declarația funcției var myCalc = function() ( // repetare peste toți parametrii folosind bucla for var i, sum = 0; for (i = 0; i lt; arguments.length; i++) ( sum += arguments[i ] ; ) // returnează suma ca rezultat returnează suma; ) // apel de funcție (ieșire către consolă) console.log(myCalc(4, 20, 17, -6));

Ca rezultat, obiectul argumente poate fi implementat în corpul funcției:

  • verificarea numărului de argumente transmise;
  • procesând orice număr de parametri.

Pe lângă funcția în sine, alte funcții care se află în ea au și acces la argumentele care îi sunt transmise în timpul etapei de apel.

Funcția mainF(p1, p2) ( function childF() ( console.log("p1 = " + p1 + "; p2 = " + p2); ) childF(); ) mainF(3, 5); // p1 = 3; p2 = 5 mainF(4, 7); // p1 = 4; p2 = 7

Valoarea implicită a parametrului

Începând cu ECMAScript 2015 (6) parametrul funcției puteți seta valoarea pe care o va avea implicit.

De exemplu, să setăm parametrul „culoare” la valoarea sa implicită „#009688”:

Funcția setBGColor(culoare = "#009688") ( document.body.style.backgroundColor = culoare; ) setBGColor(); // culoarea de fundal va fi #009688 setBGColor(„red”); // culoarea de fundal va fi roșie

Înainte de ECMAScript 2015, puteai seta un parametru la o valoare implicită, de exemplu, era așa:

Funcția setBGColor(culoare) ( culoare = culoare !== nedefinită ? culoare: „#009688”; // setează culoarea la valoarea implicită „#009688” document.body.style.backgroundColor = culoare; )

Restul parametrilor

Dacă, atunci când apelați o funcție, îi transmiteți mai multe argumente decât are parametrii, atunci îi puteți obține pe cei rămași folosind așa-numitele parametrii rămași (patametre de repaus). Această caracteristică a apărut în limbaj începând cu ECMAScript 2015.

// ...nums sunt parametrii rămași, care pot fi accesați în acest caz prin nume nums function doMath(mathAction, ...nums) ( var rezultat = 0; nums.forEach(function(value)) ( ​​switch ( mathAction) (caz „sumă”: rezultat += valoare; pauză; caz „sumCube”: rezultat += valoare**3; pauză; caz „sumăPătrat”: rezultat += valoare**2; pauză; deafult: rezultat = 0 ; ) ) ) returnează rezultatul; ) 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)

declarație de returnare

Instrucțiunea return are scopul de a returna valoarea sau rezultatul evaluării expresiei funcției curente. Valoarea sau expresia trebuie separată de returnare printr-un spațiu. În plus, instrucțiunea return încheie execuția funcției, adică. toate instrucțiunile care le urmează nu vor fi executate.

O funcție din JavaScript returnează întotdeauna un rezultat, indiferent dacă instrucțiunea return este folosită sau nu.

// returnează funcția de funcție sayWelcome (userFirstName, userLastName) ( dacă ((!userFirstName) || (!userLastName)) returnează „Bun venit, utilizator anonim”; altfel returnează „Welcome,” + userLastName + " " + userFirstName ; ) // declarație variabilă person var person; // atribuie rezultatul funcției sayWelcome variabilei persoană persoană = sayWelcome("Ivan","Ivanov"); // printeaza valoarea variabilei in consola console.log(persoana); //Instrucțiune care va afișa în consolă rezultatul funcției sayWelcome console.log(sayWelcome("Peter","Petrov")); //Instrucțiune care va afișa în consolă rezultatul funcției sayWelcome console.log(sayWelcome("Sidorov")); JavaScript - Funcție cu validare a parametrilor

O funcție din JavaScript returnează întotdeauna un rezultat ca rezultat al execuției sale, chiar dacă nu este definită în mod explicit folosind instrucțiunea return. Acest rezultat este nedefinit.

// 1. o funcție care nu returnează nicio funcție de rezultat sayWelcome (userFirstName, userLastName) ( console.log("Welcome, " + userLastName + " " + userFirstName); ) // încearcă să obțină rezultatul de la o funcție care nu nu returnează nimic console .log(sayWelcome ("Ivan", "Ivanov")); // 2. funcție care conține o instrucțiune return fără o funcție de valoare sayDay (day) ( zi = "Azi, " + zi; return; // această instrucțiune nu va fi executată deoarece vine după instrucțiunea return console.log(day) ; ) // încercați să obțineți rezultatul funcției care conține instrucțiunea return fără o valoare console.log(sayDay("21 februarie 2016")); JavaScript - Obține valoare dintr-o funcție care nu returnează nimic

Același rezultat va fi obținut dacă nu este specificată o valoare de returnare pentru instrucțiunea de returnare.

Supraîncărcarea funcției în JavaScript

Supraîncărcarea funcției în programare este capacitatea de a declara mai multe funcții cu același nume în același domeniu. Astfel de funcții diferă între ele prin tipul și numărul de argumente. Fiecare funcție are propria sa logică de programare. Supraîncărcarea funcției este utilizată astfel încât acțiuni similare să poată fi efectuate folosind același nume de funcție.

Limbajul JavaScript nu acceptă supraîncărcarea funcțiilor în modul în care este implementat, de exemplu, în limbaje asemănătoare C. Acestea. în JavaScript, nu puteți crea mai multe funcții cu același nume care sunt în același domeniu.

Funcționalități similare pot fi implementate în JavaScript utilizând următorii pași:

  • Pentru a verifica dacă un argument a fost transmis sau nu, utilizați o condiție cu verificarea valorii sale pentru undefined .
  • Pentru a verifica numărul de argumente transmise unei funcții, utilizați proprietatea lungimii argumente a obiectului.
  • Pentru a afla tipul valorii argumentului transmis, utilizați operatorii typeof sau instanceof.
  • Pentru a lucra cu un număr variabil de argumente, utilizați obiectul arguments.
  • Începând cu ECMAScript6, puteți specifica valori implicite pentru argumente.

De exemplu, să creăm o funcție care poate fi apelată cu unul sau două argumente:

//declararea unei funcții care schimbă culoarea de fundal a elementelor funcția setBgColor(bgColor,elements) ( //dacă parametrul elementelor nu este specificat la apelarea if (elements=== undefined) ( //apoi setați valoarea sa la "div" elemente = "div "; ) // obțineți toate elementele elemente = $(elemente); // parcurgeți toate elementele și setați-le la elementele de culoare de fundal specificate. each(function()( $(this).css("background) -color",bgColor) ; )); ) /*Apelați funcția setBgColor cu un parametru. pentru că 2 nu este specificat, atunci această funcție va schimba culoarea de fundal a tuturor elementelor div.*/ setBgColor("verde"); /*Apelați funcția setBgColor cu 2 parametri. pentru că 2 este setat, atunci această funcție va schimba doar culoarea de fundal a elementelor butonului.*/ setBgColor("#ff0000","button");

Să facem câteva modificări în codul de mai sus. Și anume, specificăm valoarea implicită pentru al doilea parametru:

//declararea unei funcții care schimbă culoarea de fundal a elementelor //parametrul elementelor este setat la „div” implicit funcția setBgColor(bgColor,elements = "div") ( //obține toate elementele elemente = $(elemente); / /iterează toate elementele și setează-le culoarea de fundal specificată elements.each(function()( $(this).css("background-color",bgColor); )); ) //apelează funcția setBgColor, specificând un parametru setBgColor(„verde”); //apelați funcția setBgColor, specificând 2 parametri setBgColor("#ff0000","button");

Un exemplu de implementare a unei funcții „supraîncărcate” în JavaScript care calculează numărul de calorii de care are nevoie o persoană pe zi:

// descrierea funcției funcția countCal(sex, înălțime) ( // parametri: sex (sex) și înălțime (înălțime) var rezultat; if ((sex === 0) || (sex === „bărbat”)) ( rezultat = (înălțime - 100) * 20; ) else if ((sex === 1) || (sex === „femeie”)) ( rezultat = (înălțime - 105) * 19; ) dacă (rezultat) ( // argumente - nivelul de activitate if (argumente) ( rezultat *= argumente; ) console.log("Numărul de calorii pentru viața normală: " + rezultat); ) else ( console.log ("Parametri nevalidi"); ) ) / * apelarea functiei si trecerea acesteia 2 argumente (1 - "man", poate fi accesat cu numele sex si argumente; 2 - valoarea 185, poate fi accesata cu numele sex si argumente) */ countCal("man", 185); /* apelarea funcției și transmiterea a 3 parametri, deși doar 2 sunt prezenți în descrierea funcției (în acest caz, puteți obține valoarea a 3 parametri doar ca argumente) */ countCal(0, 185, 2);

recursiunea

Recursiunea este un apel în interiorul corpului al unei anumite funcții către sine.

Un apel de funcție se face de obicei în funcție de modul în care este declarat prin nume sau printr-o variabilă care conține o referință la această funcție.

Funcția fact(n) ( if (n === 1) ( return 1; ) return fact(n-1) * n; ) console.log(fact(5)); // 120

Puteți apela o funcție în corpul său nu numai după nume, ci și folosind proprietatea apelat a obiectului arguments. Dar este mai bine să nu folosiți această proprietate, deoarece. este depășit. În afară de asta, nu funcționează deloc în modul strict.

Ce sunt funcțiile încorporate (standard)?

JavaScript are un set imens de funcții încorporate (standard). Aceste funcții sunt deja descrise în motorul browserului însuși. Aproape toate sunt metode ale unuia sau altuia obiect.

De exemplu, pentru a apela alerta de funcție (metodă) încorporată, nu trebuie să fie declarată în prealabil. Este deja descris în browser. Metoda de alertă este apelată prin specificarea unui nume, a parantezelor și a unui argument în interiorul acestora. Această metodă este concepută pentru a afișa un mesaj pe ecran sub forma unei casete de dialog. Mesajul text este preluat din valoarea parametrului acestei funcții.

// apelează funcția alert alert("Un text"); JavaScript - Apelarea funcției de alertă

Funcțiile sunt un concept cheie în JavaScript. Cea mai importantă caracteristică a limbajului este suportul pentru funcții de primă clasă (funcționează ca cetățean de primă clasă). Orice funcția este un obiect,și, prin urmare, poate fi manipulat ca obiect, în special:

  • trece ca argument și returnează ca rezultat la apelarea altor funcții (funcții de ordin superior);
  • creați în mod anonim și atribuiți ca valori variabilelor sau proprietăților obiectelor.

Acest lucru determină puterea de expresie ridicată a JavaScript și îi permite să fie clasificat ca un limbaj care implementează paradigma de programare funcțională (care în sine este foarte cool din multe motive).

Funcție în JavaScript un tip special de obiecte care vă permite să formalizați o anumită logică de comportament și prelucrare a datelor prin intermediul limbajului.

Pentru a înțelege cum funcționează funcțiile, este necesar (și suficient?) să aveți o idee despre următoarele puncte:

Declarație de funcție

Funcții ale formei „declarație de funcție”

Declarație de funcție ( definirea funcției, sau declarație de funcție, sau instrucțiunea funcției) constă din cuvântul cheie al funcției și din următoarele părți:

  • Numele funcției.
  • O listă de parametri (luați de funcție) încadrați în paranteze () și despărțiți prin virgule.
  • Instrucțiunile care vor fi executate după un apel de funcție sunt cuprinse între acolade ( ).

De exemplu, următorul cod declară o funcție simplă numită pătrat:

funcția pătrat(număr) ( returnează numărul * număr; )

Funcția pătrat preia un parametru, numit număr. Constă dintr-o singură instrucțiune, ceea ce înseamnă să returnezi parametrul acestei funcții (este un număr) înmulțit cu ea însăși. Instrucțiunea return specifică valoarea care va fi returnată de funcție.

număr return * număr;

Parametrii primitivi (cum ar fi un număr) sunt transferați funcției după valoare; sens este transmis funcției, dar dacă funcția modifică valoarea parametrului, această modificare nu va fi reflectată global sau după apelul funcției.

Dacă treceți un obiect ca parametru (nu un element primitiv, de exemplu, sau obiecte definite de utilizator) și funcția modifică o proprietate a obiectului transmis acestuia, acea modificare va fi vizibilă în afara funcției, așa cum se arată în exemplul următor :

Funcția myFunc(theObject) ( theObject.make = "Toyota"; ) var mycar = (marca: "Honda", model: "Accord", anul: 1998); var x, y; x = mycar.make; // x primește valoarea „Honda” myFunc(mycar); y=mycar.make; // y este setat la „Toyota” // (proprietatea a fost schimbată de funcție)

Funcții de forma „expresie de definire a funcției”

O funcție de forma „instrucțiune de declarare a funcției” este, în sintaxă, o instrucțiune ( afirmație), o altă funcție poate fi de forma „expresie de definire a funcției”. O astfel de funcție poate fi anonim(nu are nume). De exemplu, funcția pătrat poate fi numită astfel:

Var pătrat = funcție(număr) ( returnează numărul * număr; ); var x = pătrat(4); // x primește valoarea 16

Cu toate acestea, numele poate fi, de asemenea, atribuit pentru a se autodenomina în cadrul funcției în sine și pentru depanator ( depanator) pentru a identifica funcția în pistele stivei ( stivă urme; „urmă” - „urmă” / „amprentă”).

Var factorial = funcția fac(n) ( return n< 2 ? 1: n * fac(n - 1); }; console.log(factorial(3));

Funcțiile de forma „expresie de definire a funcției” sunt convenabile atunci când o funcție este transmisă ca argument unei alte funcții. Următorul exemplu arată o funcție de hartă care ar trebui să ia o funcție ca prim argument și o matrice ca al doilea.

Funcție map(f, a) ( var rezultat = , // Creați o nouă matrice i; pentru (i = 0; i != a.length; i++) rezultat[i] = f(a[i]); returnează rezultat ;)

În codul următor, funcția noastră ia o funcție care este o expresie de definiție a funcției și o execută pentru fiecare element al matricei primite ca al doilea argument.

Funcție map(f, a) ( var rezultat = ; // Creați o nouă matrice var i; // Declarați variabila pentru (i = 0; i != a.length; i++) rezultat[i] = f(a[i ]); returnează rezultat; ) var f = function(x) ( return x * x * x; ) var numere = ; var cub = map(f,numbers); jurnalul consolei(cubul);

Funcția returnează: .

În JavaScript, o funcție poate fi declarată cu o condiție. De exemplu, următoarea funcție va fi atribuită myFunc numai dacă num este 0:

Var myFunc; if (num === 0) ( myFunc = function(theObject) ( theObject.make = "Toyota"; ) )

Pe lângă declarațiile de funcții descrise aici, puteți utiliza și constructorul Funcție pentru a crea funcții dintr-un șir în timpul rulării ( timpul de rulare), ca .

Metodă este o funcție care este o proprietate a unui obiect. Puteți afla mai multe despre obiecte și metode la linkul: Lucrul cu obiecte.

Apeluri de funcții

Declarația funcției nu o execută. O declarație de funcție denumește pur și simplu funcția și specifică ce trebuie făcut atunci când funcția este apelată. Apel funcția realizează de fapt acțiunile specificate cu parametrii specificați. De exemplu, dacă definiți o funcție pătrată, o puteți numi astfel:

pătrat(5);

Această instrucțiune apelează funcția cu argumentul 5. Funcția își apelează instrucțiunile și returnează valoarea 25.

Funcțiile pot fi în domeniul de aplicare atunci când sunt deja definite, dar funcțiile de forma „instrucțiune de declarare a funcției” pot fi eliminate ( ridicare - ridicarea), la fel ca în acest exemplu:

Console.log(pătrat(5)); /* ... */ funcția pătrat(n) ( returnează n * n; )

Scopul unei funcții este funcția în care este definită, sau întregul program dacă este declarat la un nivel superior.

Notă: Acest lucru funcționează numai atunci când declarația funcției folosește sintaxa de mai sus (adică funcția funcName()()). Codul de mai jos nu va funcționa. Aceasta înseamnă că ridicarea funcției funcționează numai cu declararea funcției și nu funcționează cu expresia funcției.

Console.log(pătrat); // pătratul este ridicat cu valoare nedefinită. console.log(pătrat(5)); // TypeError: pătratul nu este o funcție var square = function(n) ( return n * n; )

Argumentele funcției nu se limitează la șiruri și numere. Puteți trece obiecte întregi unei funcții. Funcția show_props() (declarată în Lucrul cu obiecte) este un exemplu de funcție care ia obiectele ca argument.

O funcție se poate autodenomina. De exemplu, iată o funcție factorială recursivă:

Funcția factorial(n) ( dacă ((n === 0) || (n === 1)) returnează 1; altfel returnează (n * factorial(n - 1)); )

Apoi puteți calcula factorii de la unu la cinci astfel:

Var a, b, c, d, e; a = factorial(1); // a obține valoarea 1 b = factorial(2); // b obține valoarea 2 c = factorial(3); // c obține valoarea 6 d = factorial(4); // d primește valoarea 24 e = factorial(5); // e primește valoarea 120

Există și alte moduri de a apela o funcție. Există cazuri frecvente în care funcțiile trebuie apelate dinamic sau numerele argumentelor funcției trebuie să fie modificate sau o funcție trebuie apelată într-un context specific. Se dovedește că funcțiile în sine sunt obiecte, iar acele obiecte au, la rândul lor, metode (vezi obiect). Una dintre ele este o metodă, a cărei utilizare poate atinge acest obiectiv.

Domeniul de aplicare a funcției

(sfera funcției)

Variabilele declarate într-o funcție nu pot fi accesate oriunde în afara acelei funcții, astfel încât variabilele (care sunt necesare în mod special pentru funcție) sunt declarate numai în domeniul de aplicare al funcției. În acest caz, funcția are acces la toate variabilele și funcțiile declarate în domeniul său. Cu alte cuvinte, o funcție declarată în domeniul global are acces la toate variabilele din domeniul global. O funcție declarată în interiorul unei alte funcții are în continuare acces la toate variabilele funcției sale părinte și la alte variabile la care această funcție părinte are acces.

// Următoarele variabile sunt declarate în domeniul global var num1 = 20, num2 = 3, name = "Chamahk"; // Această funcție este declarată în funcția global scope multiply() ( return num1 * num2; ) multiply(); // returnează 60 // Exemplu de funcție imbricată funcție getScore() ( var num1 = 2, num2 = 3; function add() ( return name + " scored " + (num1 + num2); ) return add(); ) getScore( ); // returnează „Chamahk a marcat 5”

Scop și funcții de stivă

(stiva de funcții)

recursiunea

O funcție se poate autodenomina. Trei moduri de a o numi:

  1. după numele funcției
  2. printr-o variabilă care se referă la o funcție

De exemplu, luați în considerare următoarea funcție:

Var foo = function bar() ( // instrucțiunile merg aici );

În interiorul funcției ( corp funcțional) următoarele apeluri sunt toate echivalente:

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

O funcție care se autoapelează este numită functie recursiva (functie recursiva). Se pare că recursiunea este similară cu o buclă ( buclă). Ambele apelează un cod de mai multe ori și ambele necesită o condiție (pentru a evita o buclă infinită, sau mai degrabă o recursivitate infinită). De exemplu, următoarea buclă:

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

ar putea fi schimbată într-o funcție recursivă și apelând această funcție:

Bucla funcției(x) ( dacă (x >= 10) // „x >= 10” este condiția finală (la fel ca „!(x< 10)") return; // делать что-то loop(x + 1); // рекурсионный вызов } loop(0);

Cu toate acestea, unii algoritmi nu pot fi simple bucle repetate. De exemplu, obținerea tuturor elementelor unei structuri arborescente (de exemplu, ) este cel mai ușor implementată folosind recursiunea:

Funcția walkTree(node) ( dacă (nodul == null) // return; // face ceva cu elemente pentru (var i = 0; i< node.childNodes.length; i++) { walkTree(node.childNodes[i]); } }

În comparație cu funcția buclă, fiecare apel recursiv în sine provoacă multe apeluri recursive.

Este, de asemenea, posibil să faceți unii algoritmi recursivi nerecursivi, dar adesea logica lor este foarte complexă și ar necesita utilizarea unei stive ( grămadă). De fapt, recursiunea folosește stach: function stack.

Comportamentul stivei poate fi văzut în următorul exemplu:

Funcția foo(i) ( dacă (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

Funcții imbricate și închideri

Puteți imbrica o funcție în alta. funcție imbricată ( funcție imbricată;interior) privat ( privat) și este plasat într-o altă funcție ( exterior). Așa se formează închidere (închidere). O închidere este o expresie (de obicei o funcție) care poate avea variabile libere împreună cu un mediu care leagă acele variabile (care „se închide” ( închide) expresie).

Deoarece o funcție imbricată este o închidere, aceasta înseamnă că o funcție imbricată poate „moșteni” ( moşteni) argumente și variabile ale funcției în care este imbricată. Cu alte cuvinte, funcția imbricată conține domeniul de aplicare al exteriorului ( "exterior") funcții.

Rezuma:

  • Funcția imbricată are acces la toate instrucțiunile funcției externe.
  • O funcție imbricată formează o închidere: poate folosi argumentele și variabilele funcției exterioare, în timp ce funcția exterioară nu poate folosi argumentele și variabilele funcției imbricate.

Următorul exemplu arată o funcție imbricată:

Funcția addSquares(a, b) ( funcție square(x) ( return x * x; ) return square(a) + square(b); ) a = addSquares(2, 3); // returnează 13 b = addSquares(3, 4); // returnează 25 c = addSquares(4, 5); // returnează 41

Deoarece funcția imbricată formează o închidere, puteți apela funcția exterioară și puteți oferi argumente pentru ambele funcții (pentru exterior și interior).

Function outside(x) ( function inside(y) ( return x + y; ) return inside; ) fn_inside = outside(3); // Gândește-te: dă-mi o funcție pentru a // trece 3 rezultat = fn_inside(5); // returnează 8 rezultat1 = exterior(3)(5); // returnează 8

Salvarea variabilelor

Rețineți că valoarea lui x a fost păstrată când a fost returnat interior. Închiderea trebuie să păstreze argumentele și variabilele în întregul domeniu. Deoarece fiecare apel oferă argumente potențial diferite, este creată o nouă închidere pentru fiecare apel către exterior. Memoria poate fi ștearsă numai atunci când în interior a revenit deja și nu mai este disponibilă.

Acest lucru nu este diferit de stocarea referințelor în alte obiecte, dar este adesea mai puțin evident, deoarece referințele nu sunt setate direct și nu pot fi căutate acolo.

Mai multe niveluri de imbricare a funcțiilor (funcții cu imbricare multiple)

Funcțiile pot fi introduse de mai multe ori, de ex. funcția (A) stochează funcția (B) care stochează funcția (C) în sine. Ambele funcții B și C formează închideri, deci B are acces la variabilele și argumentele lui A, iar C are același acces la B. În plus, deoarece C are acces la B care are același acces la A, C are și astfel de acelasi acces la A. Astfel, cloures pot stoca mai multe lunete; ele stochează recursiv domeniul de aplicare al funcţiilor care îl conţin. Se numeste înlănţuire (lanț - lanț; De ce se numește „înlănțuire” va fi explicat mai târziu)

Luați în considerare următorul exemplu:

Funcția A(x) ( funcția B(y) ( funcția C(z) ( console. log(x + y + z); ) C(3); ) B(2); ) A(1); // consola va afișa 6 (1 + 2 + 3)

În acest exemplu, C are acces la y a funcției B și x a funcției A. Acest lucru se întâmplă deoarece:

  1. Funcția B formează o închidere care include A , adică. B are acces la argumentele și variabilele funcției A .
  2. Funcția C formează o închidere care include B .
  3. Deoarece închiderea funcției B include A, atunci închiderea C include și A, C are acces la argumentele și variabilele ambelor funcții B Și A. Cu alte cuvinte, C conectează lanţ (lanţ) domeniile funcțiilor B și A, în această ordine.

Reversul, însă, nu este adevărat. A nu are acces la variabilele și argumentele lui C, deoarece A nu are acces la B. Deci C rămâne privat doar pentru B .

Conflicte de nume

Când două argumente sau variabile din domeniul de aplicare a unei închideri au același nume, conflict de nume (conflict de nume). Mai imbricat ( mai interioară) domeniul de aplicare are prioritate, deci domeniul imbricat are cea mai mare prioritate și invers. Acesta este un lanț de domenii ( lanțul domeniului de aplicare). Prima legătură este cel mai profund domeniu și invers. Luați în considerare următoarele:

Function outside() ( var x = 5; function inside(x) ( return x * 2; ) return inside; ) outside()(10); // returnează 20 în loc de 10

A apărut un conflict de nume în instrucțiunea return x * 2 între parametrul x al funcției interne și variabila x a funcției externe. Lanțul domeniului de aplicare aici va fi astfel: ( în interior ==> în exterior ==> obiect global ( obiect global)). Prin urmare, x interior are prioritate față de exterior și obținem înapoi 20 (= 10 * 2) în loc de 10 (= 5 * 2).

Închideri

(Închideri)

Închiderile sunt una dintre principalele caracteristici ale JavaScript. JavaScript permite imbricarea funcțiilor și oferă funcției imbricate acces deplin la toate variabilele și funcțiile declarate în interiorul funcției externe (și la alte variabile și funcții la care funcția externă are acces).

Cu toate acestea, funcția exterioară nu are acces la variabilele și funcțiile declarate în funcția internă. Aceasta oferă un fel de încapsulare pentru variabilele dintr-o funcție imbricată.

De asemenea, deoarece funcția imbricată are acces la sfera funcției exterioare, variabilele și funcțiile declarate în funcția exterioară vor continua să existe și după execuția acesteia pentru funcția imbricată, dacă se păstrează accesul asupra lor și asupra acesteia (adică variabilele declarate în funcţiile exterioare sunt reţinute numai dacă funcţia interioară le apelează).

Închiderea este creată atunci când funcția imbricată devine cumva disponibilă într-un domeniu în afara funcției exterioare.

Var pet = function(name) ( // Funcția exterioară a declarat variabila "nume" var getName = function() ( return name; // Funcția imbricată are acces la "numele" funcției externe ) return getName; / / Returnează funcția imbricată, deci păstrând accesul // la ea pentru un alt domeniu ) myPet = pet("Vivie"); animalul meu(); // Returnează „Vivie”, // deoarece chiar și după executarea funcției externe // numele este păstrat pentru funcția imbricată

Un exemplu mai complex este prezentat mai jos. Un obiect cu metode de manipulare a unei funcții imbricate de către o funcție exterioară poate fi returnat ( întoarcere).

Var createPet = function(name) ( var sex; return ( setName: function(newName) (nume = newName; ), getName: function() ( return name; ), getSex: function() ( return sex; ), setSex: function(newSex) ( if(typeof newSex === „șir” && (newSex.toLowerCase() === „bărbat” || newSex.toLowerCase() === „femeie”)) ( sex = newSex; ) ) ) ) var pet = createPet("Vivie"); pet.getName(); // Vivie pet.setName("Oliver"); pet.setSex ("masculin"); pet.getSex(); // animal de companie masculin.getName(); // Oliver

În codul de mai sus, variabila nume a funcției exterioare este accesibilă funcției imbricate și nu există altă modalitate de a accesa variabilele imbricate decât prin intermediul funcției imbricate. Variabilele imbricate ale unei funcții imbricate sunt depozite sigure pentru argumente și variabile externe. Acestea conțin date „constante” și „încapsulate” pentru a lucra cu funcții imbricate. Funcțiile nici nu trebuie să fie atribuite unei variabile sau să aibă un nume.

Var getCode = (function() ( var apiCode = "0]Eal(eh&2"; // Un cod pe care nu dorim ca cei din afară să-l poată modifica... return function() ( return apiCode; ); )()) ; getCode(); // Returnează apiCode

Cu toate acestea, există o serie de capcane de care trebuie să fiți conștienți atunci când utilizați dispozitivele de închidere. Dacă o funcție privată definește o variabilă cu același nume cu numele variabilei în domeniul exterior, nu există nicio modalitate de a face referire la variabila în domeniul exterior din nou.

Var createPet = function(name) ( // Funcția exterioară definește o variabilă numită „nume". return ( setName: function(name) ( // Funcția inclusă definește și o variabilă numită „nume". nume = nume; // Cum accesăm „numele” definit de funcția exterioară? ) ) )

Folosind obiectul arguments

Obiectul argumente al funcției este o pseudo-matrice. În cadrul unei funcții, puteți face referire la argumente ca acesta:

Argumente[i]

unde i este numărul de index al argumentului, începând de la 0. Primul argument transmis funcției este accesat ca argumente . Și pentru a obține numărul tuturor argumentelor - arguments.length .

Cu obiectul arguments, puteți apela o funcție transmițându-i mai multe argumente decât ați declarat oficial că acceptați. Acest lucru este foarte util dacă nu știi exact câte argumente ar trebui să ia funcția ta. Puteți utiliza arguments.length pentru a determina numărul de argumente transmise unei funcții și apoi accesați fiecare argument folosind obiectul arguments.

De exemplu, luați în considerare o funcție care concatenează mai multe șiruri. Singurul argument formal al funcției va fi un șir care specifică caracterele care separă elementele de concatenat. Funcția este definită astfel:

Funcția myConcat(separator) ( var rezultat = ""; var i; // repetare prin argumente pentru (i = 1; i< arguments.length; i++) { result += arguments[i] + separator; } return result; }

Puteți trece orice număr de argumente acestei funcție și va concatena fiecare argument într-un singur șir.

// returnează „roșu, portocaliu, albastru, „ myConcat(”, „, „roșu”, „orange”, „albastru”); // returnează "elefant; girafă; leu; ghepard; " myConcat("; ", "elefant", "girafă", "leu", "ghepard"); // returneaza "salvie. busuioc. oregano. piper. patrunjel. " myConcat(". ", "salvie", "busuioc", "oregano", "piper", "patrunjel");

pentru că arguments este o pseudo-matrice, i se aplică unele metode de matrice, cum ar fi pentru .. în

Funcția func() ( for (valoare în argumente)( console.log(valoare); ) ) func(1, 2, 3); // 1 // 2 // 3

Notă: arguments este o pseudo-matrice, dar nu o matrice. Aceasta este o pseudo-matrice care are indecși numerotați și o proprietate de lungime. Cu toate acestea, nu are toate metodele matrice.

Parametrii de odihnă

Doi factori au influențat introducerea funcțiilor săgeată: funcțiile mai scurte și lexicul acestuia.

Funcții mai scurte

Unele modele de funcții încurajează utilizarea funcțiilor mai scurte. Comparaţie:

Var a = [ „Hidrogen”, „Heliu”, „Litiu”, „Beriliu” ]; var a2 = a.map(funcție(i) ( return s.length; )); jurnalul consolei(a2); // logs var a3 = a.map(s => s.length); jurnalul consolei(a3); // jurnalele

Vocabular asta

Înainte de funcțiile săgeată, fiecare funcție nouă și-a definit această valoare (obiect nou în cazul unui constructor, nedefinit în modul strict, obiect context dacă funcția este apelată ca metodă pe un obiect etc.). Acest lucru s-a dovedit a fi enervant în ceea ce privește stilul de programare orientată pe obiecte.

Funcție Person() ( // Constructorul Person() definește `this` ca pe sine. this.age = 0; setInterval(function growUp() ( // Fără modul strict, growUp() definește `this` ca un obiect global , care este diferit de `this` // definit de constructorul Person().this.age++; ), 1000); ) var p = new Person();

În ECMAScript 3/5, această problemă a fost rezolvată prin atribuirea valorii acesteia unei variabile care ar putea fi închisă.

Funcția Persoană() ( var self = this; // Unii aleg `that` în loc de `self`. // Alegeți unul și fiți consecvenți. self.age = 0; setInterval(function growUp() ( // callback-ul se referă la variabila `self` a cărei // valoarea este obiectul așteptat.self.age++; ), 1000); )

Consultați și Funcție în Referința JavaScript pentru mai multe informații despre funcții ca obiect.

Orice programator știe bine ce sunt funcțiile și de ce sunt necesare. Cu toate acestea, funcțiile din limbajul Javascript au unele particularități. Dacă ai programat în acest limbaj de mult timp, atunci probabil știi că există diferite . Dacă ați venit dintr-o altă limbă, atunci când citiți unele articole, cel mai probabil ați văzut aceasta, ciudată la prima vedere, declarație de funcție:

Var add = function(arg1, arg2) ( var sum = arg1 + arg2; return sum; ) var rezultat = add(5, 2); //rezultatul este acum 7

Adică, funcția, în primul rând, nu are un nume. În al doilea rând, este atribuită unei variabile, dar nu doar atribuită, dar corpul ei dispare imediat. Personal, pentru mine, care am scris anterior în limbi precum VB, C++, un astfel de anunț a provocat nedumerire și neînțelegere a modului în care funcționează și de ce să scriu așa.

Sunt obișnuit cu declararea și apelul funcției „clasice”, astfel:

Funcția add(arg1, arg2) ( var sum = arg1 + arg2; return sum; ) var rezultat = add(5, 3); //rezultatul este acum 8

Și aici ajungem la caracteristicile funcțiilor din Javascript. Pentru ușurință de înțelegere, imaginați-vă că o funcție în JS este o valoare obișnuită, cum ar fi un număr sau un șir. Puteți scrie numărul 5 în variabila rezultat, nu? Sau ceva mai complex, cum ar fi o matrice, și apoi afișați-l pe ecran? Puteți. Deci, dacă ne imaginăm că o funcție este o valoare obișnuită, deși o structură foarte complexă, atunci primul mod de declarare nu mai pare a fi ceva incredibil.

Următorul fapt interesant este o continuare logică a primului. După ce plasăm datele într-o variabilă, putem transmite date unei alte variabile folosind numele acestei variabile:

Var a = 5; var b = a; alerta(b); //ieșiri 5

Lucrul obișnuit. Acum aruncați o privire la acest cod:

Var add = function(arg1, arg2) ( var sum = arg1 + arg2; return sum; ) var calcSum = add; alert(calcSum(5, 6)); //ieșiri 11

Incepi sa ghicesti? Deoarece o funcție este ca o variabilă, o putem „propaga” prin atribuire obișnuită altor variabile, transformându-le și în funcții. Acum calcSum poate adăuga și două numere. Totuși, codul

VarcalcSum = add(1, 1); //calcSum este acum egal cu 2, aceasta nu este o funcție, ci o variabilă cu o alertă de număr(calcSum(5, 6)); //greşeală

Nu va fi executat, deoarece în prima linie am atribuit nu funcția în sine, ci rezultatul execuției acesteia (parantezele indică faptul că funcția trebuie executată, nu atribuită).

Dacă trebuie să apelați o funcție pe ea însăși, atunci acest lucru se face după cum urmează:

Var calcFact = function fact(val) ( if (val == 1) ? val: val * fact(val - 1); // calculeaza factorial folosind recursiunea ) alert(calcFact(4)); //ieșiri 24

Aici, prin atribuirea funcției unei variabile, i-am dat numele faptului. Cu toate acestea, acest nume va fi disponibil numai în cadrul funcției în sine și nicăieri altundeva. Motivele pentru aceasta se află în principiul interpretului și depășesc domeniul de aplicare al lecției.

S-ar putea să vă întrebați „Hmm, caracteristică interesantă! Dar care este avantajul de a face asta? Există situații în care este inevitabil, sau cel puțin mai convenabil decât o declarație obișnuită?”. Nu mă voi angaja să afirm că există situații în care este imposibil să faci fără o astfel de abordare, dar pot da un exemplu în care se reduce cantitatea de cod. Să presupunem că trebuie să salutați o persoană în funcție de momentul zilei:

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

După cum puteți vedea, funcțiile sunt extrem de simple, cu o singură comandă de alertă.

Dacă am decide să mergem pe calea „clasică”, atunci ar trebui să scriem trei funcții separate și apoi să le numim în condiția de testare a timpului:

Funcția goodMorning() ( alert("Bună dimineața!"); ) function goodAfternoon() ( alert("Bună ziua!"); ) function goodEvning() ( alert("Bună seara!"); ) var data = data nouă (); (date.getHours()< 12) ? goodMorning() : (date.getHours() < 18) ? goodAfternoon() : goodEvning();

Codul a crescut semnificativ din punct de vedere vizual, chiar dacă am folosit forma scurtă a declarației condiționate. Dacă presupunem că fișierul conține funcții cu adevărat importante care efectuează calcule, atunci poluarea listei cu astfel de mini-funcții care nu poartă o logică importantă și care sunt folosite cel mai probabil o singură dată, nu este o idee bună. În plus, suntem forțați să dăm fiecărei funcții un nume unic și să-l specificăm atunci când apelăm. Prin urmare, dacă trebuie să schimbați numele unuia dintre ele, va trebui să îl schimbați în două locuri, ceea ce crește probabilitatea unei erori.

În al doilea rând, dacă folosim metoda „clasică”, atunci pierdem capacitatea de a atribui o funcție unei variabile. Adică scrie

Funcția add(a, b) ( return a + b; ) var calcSum = add; calcSum(5, 5);

Deja imposibil. Prin urmare, în exemplul nostru, dacă mai trebuie să salutăm oaspetele de mai multe ori, va trebui să duplicăm acest fragment de fiecare dată:

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

Și în primul caz, va fi suficient să scrieți doar salut(); iar rezultatul va fi același.

V-am spus despre o caracteristică interesantă a funcțiilor JS și am dat exemple. Așa ai văzut asta moduri de a apela funcții în Javascript nu se limitează la o singură specie. Chiar dacă nu puteți găsi imediat utilizarea acestor caracteristici în proiectele dvs., cel puțin veți ști că astfel de caracteristici există. Și când apare o oportunitate foarte bună, puteți reduce cantitatea de cod și puteți evita confuziile și erorile inutile.!

Acest articol descrie caracteristicile Javascript la nivel de limbă: creare, opțiuni, trucuri, închideri și multe altele.

Crearea Funcțiilor

Există 3 moduri de a crea o funcție. Principala diferență ca urmare a muncii lor este că funcția numită este vizibilă peste tot, iar cea anonimă este vizibilă numai după declarație:

Funcții - Obiecte

În javascript, funcțiile sunt obiecte cu drepturi depline ale clasei Function încorporate. De aceea pot fi atribuite variabilelor, trecute și, bineînțeles, au proprietăți:

Funcția f() ( ... ) f.test = 6 ... alert(f.test) // 6

Proprietățile funcției sunt, de asemenea, disponibile în cadrul funcției, astfel încât acestea pot fi utilizate ca variabile statice.

De exemplu,

Funcția func() ( var funcObj = arguments.callee funcObj.test++ alert(funcObj.test) ) func.test = 1 func() func()

La începutul lucrării, fiecare funcție creează o variabilă argumente în interiorul ei și atribuie arguments.callee o referință la sine. Deci arguments.callee.test este o proprietate a func.test , adică un test de variabilă statică.

În exemplu, a fost imposibil să faci o misiune:

Vartest = arguments.callee.test test++

deoarece în acest caz operația ++ ar funcționa pe variabila locală test și nu pe proprietatea test a obiectului funcție.

Obiectul arguments conține, de asemenea, toate argumentele și poate fi convertit într-o matrice (deși nu este), mai multe despre acest lucru mai târziu în secțiunea despre parametri.

Domenii de aplicare

Fiecare funcție, mai precis, chiar și fiecare lansare a funcției, își stabilește propriul domeniu de aplicare individual.

Variabilele pot fi declarate oriunde. Cuvântul cheie var specifică o variabilă în domeniul curent. Dacă o uitați, atunci variabila va ajunge în obiectul fereastră globală. Sunt posibile intersecții neașteptate cu alte variabile ale ferestrei, conflicte și erori.

Spre deosebire de unele limbi, blocurile nu definesc un domeniu separat. Nu contează dacă variabila este definită în interiorul blocului sau în afara acestuia. Deci, aceste două fragmente sunt perfect echivalente:

O variabilă definită prin var este vizibilă peste tot în domeniul de aplicare, chiar înainte de instrucțiunea var. De exemplu, să facem o funcție care va schimba variabila, var pentru care este mai jos.

De exemplu:

Funcția a() ( z = 5 // va schimba z la nivel local.. // .. deoarece z este declarat prin var var z ) // șterge z test // șterge za() global pentru orice caz alert(window.z) // => nedefinit deoarece z a fost modificat local

Parametrii funcției

Funcțiile pot fi executate cu orice număr de parametri.

Dacă sunt trecuți funcției mai puțini parametri decât sunt în definiție, atunci cei lipsă sunt considerați nedefiniți.

Următoarea funcție returnează timpul necesar pentru a parcurge distanța la o viteză uniformă.

Prima dată când funcția este rulată cu argumentele distanță=10, viteză=nedefinită. De obicei, această situație, dacă este acceptată de funcție, oferă o valoare implicită:

// dacă viteza este falsă (nedefinit, 0, fals...) - înlocuiți 10 viteză = viteza || 10

Operator || în javascript nu returnează true/false , ci valoarea în sine (prima care trimite la true).

Prin urmare, este folosit pentru a seta valori implicite. În apelul nostru, viteza va fi evaluată ca nedefinită || 10 = 10 .

Deci rezultatul va fi 10/10 = 1.

A doua lansare este standard.

A treia rulare specifică câteva argumente suplimentare. Funcția nu funcționează cu argumente suplimentare, așa că sunt pur și simplu ignorate.

Ei bine, în acest din urmă caz, nu există deloc argumente, deci distanță = nedefinit și avem rezultatul împărțirii undefined/10 = NaN (Not-A-Number, a apărut o eroare).

Lucrul cu un număr nedefinit de parametri

Chiar înainte de a intra în corpul funcției, este creat automat un obiect argumente care conține

  1. Argumente de apel, începând de la zero
  2. Lungimea în proprietatea lungimii
  3. Referire la funcția însăși în proprietatea apelat

De exemplu,

Funcția func() ( for(var i=0;i

Proprietatea arguments este ca o matrice prin faptul că are o lungime și indecși numerici. De fapt, argumentele nu aparțin clasei Array și nu conține metodele acesteia, cum ar fi push , pop și altele.

Dacă tot doriți să utilizați aceste metode, de exemplu, pentru a apela o altă funcție cu aceleași argumente, dar pe lângă prima, puteți crea o matrice reală din argumente:

Var args = Array.prototype.slice.call(arguments) // .. acum args este o matrice reală de argumente.. args.shift() ...

Puteți apela o funcție pe o matrice de argumente folosind aplica:

Var func = function(a,b) ( alert(a+b) ) var arr = func.apply(null, arr) // => alert(3)

Exemplu de transmitere a unei funcții prin referință

O funcție poate fi transmisă cu ușurință ca argument unei alte funcții.

De exemplu, map preia o funcție func, o aplică fiecărui element al matricei arr și returnează tabloul rezultat:

Var map = function(func, arr) ( var rezultat = for(var i=0; i

Exemplu de utilizare:

Hartă(a alerga, ) // =

Sau puteți crea o funcție anonimă direct în apelul hărții:

// funcția anonimă triplă numerele map(funcția (a) ( returnează a*3 ), ) // =

Restrângerea parametrilor într-un obiect

Există funcții ale căror argumente variază foarte mult.

De exemplu:

// doar o parte din argumente pot fi specificate // nespecificat - calculat sau preluat implicit funcția resize(toWidth, toHeight, saveProportions, animate) ( // valori implicite saveProportions = saveProportions || true animate = animate || true toHeight = toHeight | | ...)

Un apel cu parametri opționali trebuie făcut astfel:

redimensionare (100, nul, nul, adevărat)

Pentru a evita valorile nule inutile și pentru a face codul mai ușor de înțeles, ei folosesc ceva de genul „argumente ale cuvintelor cheie” care există în Python și Ruby. Pentru a face acest lucru, mulți parametri sunt împachetati într-un singur obiect:

Funcția resize(setup) ( // valori implicite var saveProportions = setup.saveProportions || true var animate = setup.animate || true var toHeight = setup.toHeight || ... )

Apelul este acum mult mai simplu:

Var setup = (toWidth: 100, animate: true) resize(setup) // sau resize((toWidth: 100, animate: true))

Da, mult mai clar. Și dacă există mai mult de 5 parametri, atunci în general - singurul mod normal.

În plus, este mai convenabil să faci secvențe de apeluri cu un obiect precum:

var setup = (toWidth: 100, animate: true, saveProportions: false) resize(setup) setup.toWidth = 200 resize(setup)

Funcții

Funcţie este un bloc de cod JavaScript care este definit o dată și poate fi executat sau apelat de mai multe ori. Este posibil să fiți deja familiarizați cu conceptul de „funcție” cu un alt nume, cum ar fi o subrutină sau o procedură. Funcțiile pot avea parametri: o definiție de funcție poate include o listă de identificatori numiți parametri care acționează ca variabile locale în corpul funcției.

Când sunt apelate funcții, li se pot transmite valori sau argumente corespunzătoare parametrilor lor. Funcțiile își folosesc adesea argumentele pentru a calcula o valoare returnată, care este valoarea unei expresii de apelare a funcției. Pe lângă argumente, la apelarea oricărei funcție, i se mai trece o valoare care determină contextul apelului - valoarea din cuvântul cheie acest.

Funcțiile din JavaScript sunt obiecte și pot fi utilizate în multe moduri. De exemplu, funcțiile pot fi atribuite variabilelor și transmise altor funcții. Deoarece funcțiile sunt obiecte, este posibil să atribuiți valori proprietăților lor și chiar să le apelați metode.

JavaScript permite definițiile de funcții să fie imbricate în alte funcții, iar astfel de funcții vor avea acces la toate variabilele prezente în domeniul de aplicare al definiției.

Definirea funcției

O definiție a funcției începe cu un cuvânt cheie funcţie urmată de următoarele componente:

Identificator care definește numele funcției

Numele este o parte obligatorie a instrucțiunii de declarare a funcției: va fi folosit pentru a crea o nouă variabilă căreia îi va fi atribuit noul obiect funcție. În expresiile de definire a funcției, numele poate fi omis: dacă este prezent, numele se va referi la obiectul funcție doar în corpul funcției în sine.

O pereche de paranteze în jurul unei liste separate prin virgulă de zero sau mai mulți identificatori

Acești identificatori vor defini numele parametrilor funcției și pot fi utilizați ca variabile locale în corpul funcției.

O pereche de acolade cu zero sau mai multe instrucțiuni JavaScript înăuntru

Aceste instrucțiuni alcătuiesc corpul funcției: ele sunt executate de fiecare dată când funcția este apelată.

Următorul exemplu arată mai multe definiții de funcții sub formă de instrucțiuni și expresii. Rețineți că definițiile funcției ca expresii sunt utile numai dacă fac parte din expresii mai mari, cum ar fi o atribuire sau un apel de funcție, care efectuează o anumită acțiune folosind funcția nou declarată:

// Tipărește numele și valorile tuturor proprietăților funcției obiect obj printprops(obj) ( for(var p în obj) console.log(p + ": " + obj[p] + "\n"); ) // Calculeaza distanta dintre punctele (x1,y1) si (x2,y2) function distance(x1, y1, x2, y2) ( var dx = x2 - x1; var dy = y2 - y1; return Math.sqrt( dx*dx + dy*dy ); ) // Funcție recursivă (autointitulându-se) care calculează funcția factorială factorial(x) ( dacă (x)

Rețineți că în expresiile de definire a funcției, numele funcției poate fi omis. O instrucțiune de declarare a funcției declară de fapt o variabilă și îi atribuie un obiect funcție.

O expresie de definiție a funcției, în schimb, nu declară o variabilă. Cu toate acestea, expresiile de definiție au permisiunea de a specifica un nume de funcție, ca în funcția factorială de mai sus, care poate fi necesar în corpul funcției pentru a se autodenomina. Dacă o expresie de definiție a funcției include un nume, acel nume se va referi la obiectul funcției din domeniul de aplicare al funcției. De fapt, numele funcției devine o variabilă locală, accesibilă doar în corpul funcției. În cele mai multe cazuri, numele funcției nu este necesar în expresiile de definiție, ceea ce face definițiile mai compacte.

Rețineți că majoritatea (dar nu toate) funcțiile din exemplu conțin o instrucțiune return. Instrucțiunea return încheie execuția funcției și returnează valoarea expresiei acesteia (dacă este specificată) programului apelant. Dacă nu există o expresie în instrucțiunea return, aceasta returnează nedefinit. Dacă nu există nicio instrucțiune return în funcție, interpretul va executa pur și simplu toate instrucțiunile din corpul funcției și va returna nedefinit apelantului.

Majoritatea funcțiilor din exemplu evaluează o anumită valoare și folosesc o instrucțiune return pentru a returna acea valoare apelantului. Funcția printprops() este ușor diferită în acest sens: sarcina ei este de a tipări numele proprietăților unui obiect. Nu trebuie să returneze nicio valoare, deci nu există nicio instrucțiune return în funcție. Funcția printprops() va returna întotdeauna nedefinit. (Funcțiile care nu au o valoare returnată sunt uneori numite proceduri.)

Funcții de apelare

Codul de program care formează corpul unei funcții este executat nu în momentul în care funcția este definită, ci în momentul în care este apelată. Apelurile de funcții sunt efectuate folosind o expresie de apel. O expresie de invocare constă dintr-o expresie de apel de funcție care returnează un obiect funcție, urmată de paranteze cu o listă separată prin virgulă de zero sau mai multe expresii de argument în interior.

Dacă o expresie de acces la funcție este o expresie de acces la proprietate - dacă funcția este o proprietate a unui obiect sau un element al unui tablou (adică, o metodă) - atunci expresia de invocare este o expresie de invocare a unei metode. Următorul fragment demonstrează câteva exemple de expresii de apel de funcție normale:

Elemente de imprimare((x:4, vârsta: 24)); var d = distanta(1,1,5,6); var f = factorial(5) / factorial(12); f = pătrat(5);

Când o funcție este apelată, toate expresiile de argument (specificate între paranteze) sunt evaluate, iar valorile rezultate sunt utilizate ca argumente ale funcției. Aceste valori sunt atribuite parametrilor ale căror nume sunt listate în definiția funcției. În corpul funcției, expresiile de acces la parametri returnează valorile argumentelor corespunzătoare.

Când este apelată o funcție normală, valoarea returnată a funcției devine valoarea expresiei de apel. Dacă funcția revine când interpretul ajunge la sfârșitul funcției, este returnat undefined. Dacă o funcție revine ca rezultat al unei instrucțiuni return, valoarea expresiei care urmează instrucțiunii return este returnată sau nedefinită dacă instrucțiunea return nu are nicio expresie.

Metodă nu este altceva decât o funcție care este stocată ca proprietate a unui obiect. Având în vedere o funcție func și un obiect obj, puteți defini o metodă pe obiectul obj numit metoda, așa cum se arată mai jos:

// Definiți un obiect și o funcție simplă var obj = (); function func(a, b) ( return a+b;) // Adauga o metoda la obiectul obj obj.method = func; // Acum putem numi această metodă var result = obj.method(4, 5);

Cea mai obișnuită modalitate de a apela metode este de a folosi forma de operator punct de acces la proprietate, dar puteți utiliza și forma paranteze pătrate de acces la proprietate. De exemplu, ambele dintre următoarele expresii sunt expresii de apel de metodă:

Rezultat = obj.method(4, 5); rezultat = obj["metoda"](4, 5);

Argumentele și valoarea returnată a unui apel de metodă sunt tratate exact în același mod ca un apel de funcție normal. Cu toate acestea, invocarea metodei are o diferență importantă: contextul de invocare. O expresie de acces la proprietate constă din două părți: un obiect (obj în acest caz) și un nume de proprietate (metodă). În astfel de expresii de apel de metodă, obiectul obj devine contextul de apel, iar corpul funcției se poate referi la acest obiect folosind cuvântul cheie this. De exemplu:

Var obj = ( x: 0, y: 0, // Adăugați metoda: function(a, b) ( this.x = a; this.y = b; ), // O altă metodă sumă: function() ( return this .x + this.y ) ); // Apel metode obj.add(15, 4); console.log(obj.sum()); // 19

Metodele și acest cuvânt cheie sunt centrale pentru paradigma de programare orientată pe obiecte. Orice funcție folosită ca metodă primește de fapt un argument implicit - obiectul pe care a fost apelată. De obicei, metodele efectuează o anumită acțiune asupra unui obiect, iar sintaxa apelului de metodă reflectă în mod clar faptul că o funcție operează pe un obiect.

Rețineți că acesta este un cuvânt cheie, nu o variabilă sau un nume de proprietate. Sintaxa JavaScript nu permite alocarea de valori acestui element.

Argumente și parametrii funcției

În JavaScript, definițiile funcțiilor nu specifică tipurile de parametri, iar atunci când funcțiile sunt apelate, nu se efectuează verificări de tip asupra valorilor argumentelor transmise. De fapt, atunci când se apelează funcții în JavaScript, nici măcar numărul de argumente nu este verificat. Subsecțiunile de mai jos descriu ce se întâmplă dacă numărul de argumente dintr-un apel de funcție este mai mic sau mai mare decât numărul de parametri declarați. Ele demonstrează, de asemenea, cum puteți verifica în mod explicit tipurile de argumente ale funcției dacă doriți să vă asigurați că funcția nu este apelată cu argumente incorecte.

Argumente opționale

Când numărul de argumente dintr-un apel de funcție este mai mic decât numărul de parametri declarați, argumentele lipsă sunt setate la nedefinit. Este adesea convenabil să scrieți funcții, astfel încât unele dintre argumente să fie opționale și să poată fi omise atunci când funcția este apelată. În acest caz, este de dorit să se prevadă posibilitatea de a atribui parametrilor care pot fi omisi valori implicite rezonabile. De exemplu:

// Adăugați numele enumerate // ale proprietăților obiectului obj în tabloul arr și returnați-l. Dacă nu a fost transmis niciun argument // arr, creați și returnați o nouă funcție de matrice getPropertyNames(obj, /* opțional */ arr) ( dacă (arr === nedefinit) arr = ; // Dacă matricea nu este definită, creați un nou one for( var proprietate în obj) arr.push(property); return arr; ) // Această funcție poate fi apelată cu 1 sau 2 argumente: var a = getPropertyNames((x:1, y:1)); // Obține proprietățile obiectului din noua matrice getPropertyNames((z:5),a); // adaugă proprietățile noului obiect la această matrice console.log(a); // ["x", "y", "z"]

Rețineți că atunci când declarați funcții, argumentele opționale trebuie să încheie lista de argumente, astfel încât să poată fi omise. Un programator care va scrie un apel la funcția dvs. nu va putea să treacă al doilea argument și să-l omite pe primul: va fi forțat să treacă în mod explicit nedefinit în primul argument. De asemenea, rețineți comentariul /* opțional */ din definiția funcției, care subliniază faptul că parametrul este opțional.

Liste de argumente cu lungime variabilă

Dacă numărul de argumente dintr-un apel de funcție depășește numărul de nume de parametri, funcția nu mai poate accesa direct valorile nenumite. Soluția la această problemă este oferită Obiectul argumentelor. În corpul funcției, identificatorul argumente se referă la obiectul Argumente prezent în apel. Obiectul Arguments este un obiect asemănător matricei care vă permite să preluați valorile transmise unei funcții prin numerele lor în loc de numele lor.

Să presupunem că a fost definită o funcție func care necesită un singur argument x. Dacă apelați această funcție cu două argumente, atunci primul va fi disponibil în interiorul funcției cu numele parametrului x sau ca argumente. Al doilea argument va fi disponibil doar ca argumente. De asemenea, ca și matricele adevărate, argumentele au o proprietate de lungime care specifică numărul de elemente pe care le conține. Adică, în corpul unei funcții func apelate cu două argumente, arguments.length este 2.

Obiectul Argumente poate fi folosit pentru o varietate de scopuri. Următorul exemplu arată cum să îl utilizați pentru a verifica dacă o funcție a fost apelată cu numărul corect de argumente, deoarece JavaScript nu va face asta pentru dvs.:

Funcția func(x, y, z) ( // Verificați mai întâi dacă a fost transmis numărul corect de argumente dacă (arguments.length != 3) ( throw new Error("Funcție numită cu argumente " + arguments.length + ", dar necesita 3."); ) // Și acum codul funcției în sine... )

Rețineți că adesea nu este necesar să verificați numărul de argumente, ca în acest exemplu. Comportamentul implicit al interpretului JavaScript este bun pentru majoritatea cazurilor: argumentele lipsă sunt înlocuite cu nedefinite, iar argumentele suplimentare sunt pur și simplu ignorate.

Obiectul Arguments ilustrează o caracteristică importantă a funcțiilor JavaScript: acestea pot fi scrise pentru a lua orice număr de argumente. Următoarea funcție preia orice număr de argumente și returnează valoarea celui mai mare dintre ele (funcția încorporată Math.max() se comportă în mod similar):

Funcția maxNumber() ( var m = Number.NEGATIVE_INFINITY; // Buclă prin toate argumentele, găsiți și // stocați cel mai mare dintre ele pentru (var i = 0; im) m = arguments[i]; // Returnează cea mai mare valoare return m ; ) var cea mai mare = maxNumber(1, 10, 100, 2, 3, 1000, 4, 5, 10000, 6); // 10000

Funcții ca aceasta care pot lua un număr arbitrar de argumente sunt numite funcții variadice, funcții de aritate variabilă sau funcții varargs. Acest termen a apărut odată cu apariția limbajului de programare C.

Rețineți că funcțiile cu un număr variabil de argumente nu pot fi apelate cu o listă de argumente goală. Este logic să folosiți obiectul arguments atunci când scrieți o funcție care se așteaptă să primească un număr fix de argumente numite necesare, urmate de un număr arbitrar de argumente opționale fără nume.

Nu trebuie uitat că arguments nu este de fapt o matrice - este un obiect Arguments. Fiecare obiect Arguments are elemente de matrice numerotate și o proprietate de lungime, dar din punct de vedere tehnic nu este o matrice. Este mai bine să ne gândim la el ca la un obiect care are unele proprietăți enumerate.

Pe lângă elementele matricei sale, obiectul Arguments definește proprietăți apelatȘi apelant. Încercarea de a schimba valorile acestor proprietăți în modul strict ECMAScript 5 este garantată pentru a arunca o excepție TypeError. Cu toate acestea, în modul lax, standardul ECMAScript afirmă că proprietatea apelat se referă la funcția care se execută în prezent. Proprietatea apelantului nu este standard, dar este prezentă în multe implementări și se referă la funcția care a apelat-o pe cea curentă.

Proprietatea apelant poate fi folosită pentru a accesa stiva de apeluri, iar proprietatea apelant este utilă în special pentru apelarea recursiv a funcțiilor fără nume:

Var factorial = funcția(x) (dacă (x

Proprietăți și metode ale funcției

Am văzut că funcțiile pot fi folosite ca valori în programele JavaScript. Operatorul typeof returnează șirul „funcție” pentru funcții, dar funcțiile JavaScript sunt într-adevăr un tip special de obiect. Și deoarece funcțiile sunt obiecte, ele au proprietăți și metode ca orice alte obiecte. Există chiar și un constructor Function() care creează noi obiecte funcție. Următoarele subsecțiuni descriu proprietățile și metodele funcțiilor.

proprietatea lungimii

În corpul funcției, proprietatea arguments.length determină numărul de argumente transmise funcției. Cu toate acestea, proprietatea de lungime a funcției în sine are un înțeles diferit. Această proprietate numai în citire returnează numărul de argumente pe care funcția se așteaptă să le primească - numărul de parametri declarați.

Următorul fragment definește o funcție numită check() care primește o serie de argumente de la o altă funcție. Acesta compară proprietatea arguments.length (numărul de argumente transmise efectiv) cu proprietatea arguments.callee.length (numărul de argumente așteptate) pentru a determina dacă funcției i-au fost transmise atâtea argumente cât se așteaptă. Dacă valorile nu se potrivesc, se face o excepție. Funcția check() este urmată de funcția de testare func(), care demonstrează cum se utilizează funcția check():

// Această funcție folosește arguments.callee, deci // nu va funcționa în modul strict function check(args) ( var actual = args.length; // Numărul real de argumente var așteptat = args.callee.length; // Argumente de număr așteptat dacă (actual !== așteptat) // Dacă nu se potrivesc, este aruncată o excepție throw new Error("așteptată: " + așteptat + "; primit " + actual); ) function func(x, y , z) ( // Verificați numărul de argumente așteptate și trecute efectiv verifica (argumente); // Rulați acum restul funcției return x + y + z; )

proprietate prototip

Fiecare funcție are o proprietate prototip care se referă la un obiect cunoscut sub numele de obiect prototip. Fiecare funcție are propriul său obiect prototip. Când o funcție este folosită ca constructor, obiectul nou creat moștenește proprietățile acelui obiect prototip.

Prototipurile și proprietatea prototipului au fost discutate într-un articol anterior.

metodele call() și apply().

Metodele call() și apply() vă permit să apelați o funcție indirect ca și cum ar fi o metodă a unui alt obiect. Primul argument atât pentru call() cât și pentru apply() este obiectul pe care este apelată funcția; acest argument definește contextul apelului și devine valoarea cuvântului cheie this din corpul funcției. Pentru a apela funcția func() (fără argumente) ca metodă a obiectului obj, puteți utiliza oricare dintre metode, call() sau apply():

Func.call(obj); func apply(obj);

Oricare mod de a-l apela este echivalent cu următorul fragment (presupunând că obj nu are o proprietate numită m):

obj.m = func; // Faceți temporar funcția o metodă obj obj.m(); // Numiți-o fără argumente. șterge obj.m; // Eliminați metoda temporară.

În modul strict ECMAScript 5, primul argument al metodelor call() și apply() devine valoarea this, chiar dacă este o valoare simplă, nulă sau nedefinită. În ECMAScript 3 și în modul non-strict, null și undefined sunt înlocuite cu obiectul global, iar o valoare simplă cu obiectul wrapper corespunzător.

Toate celelalte argumente ale metodei call() care urmează primului argument, care specifică contextul apelului, sunt transmise funcției apelate. Metoda apply() acţionează ca metoda call(), cu excepţia faptului că argumentele funcţiei sunt transmise ca o matrice. Dacă o funcție este capabilă să gestioneze un număr arbitrar de argumente, metoda apply() poate fi folosită pentru a apela o astfel de funcție în contextul unui tablou de lungime arbitrară.

Următorul exemplu demonstrează utilizarea practică a metodei call():

// Mai jos sunt două funcții care afișează proprietățile și // valorile proprietăților unui obiect arbitrar. Metoda de afișare // este transmisă ca argument func function print1(func, obj) ( pentru (n în obj) func(n +": " + obj[n]); ) function print2(func, objDevice, obj) (pentru ( n în obj) func.call(objDevice, n +": " + obj[n]); ) var obj = (x:5, y:10); print2(document.write, document, obj); // Funcționează corect print2(console.log, console, obj); print1(document.write, obj); // O excepție de invocare ilegală va fi ridicată deoarece print1(console.log, obj); // nu pot apela aceste metode fără un obiect context

metoda bind().

Metoda bind() a apărut pentru prima dată în ECMAScript 5, dar este ușor de imitat în ECMAScript 3. După cum sugerează și numele, scopul principal al metodei bind() este de a lega o funcție la un obiect. Dacă apelați metoda bind() a func și îi treceți un obiect obj, va returna o nouă funcție. Apelarea noii funcție (ca o funcție normală) va apela funcția originală func ca metodă a obiectului obj. Orice argumente transmise noii funcție vor fi transmise funcției inițiale. De exemplu:

// Funcție pentru a lega funcția func(y) ( return this.x + y; ) var obj = (x:1); // Obiect de legat la var g = func.bind(obj); // Apelarea g(x) va apela obj.func(x)

Acest tip de legare este ușor de implementat în ECMAScript 3, după cum se arată mai jos:

// Returnează o funcție care apelează func ca metodă pe obj // și îi transmite toate argumentele sale function bind(func, obj) ( if (func.bind) return func.bind(obj); // Folosește metoda bind dacă este disponibil, altfel returnează funcția() ( // Altfel se leagă ca mai jos return function. apply(obj, argumente); ); )

Metoda bind() din ECMAScript 5 face mai mult decât să lege o funcție la un obiect. De asemenea, efectuează o aplicație parțială: în plus față de această valoare, toate argumentele transmise metodei bind() după primul argument vor fi legate. Aplicarea parțială este o tehnică comună în programarea funcțională și uneori este numită curry.

Top articole similare