Top 11 (și mai multe!) Funcții JavaScript care trebuie cunoscute

Dezvoltă cod inteligent! Devino un expert JavaScript mai rapid, mai eficient și mai mulțumit, prin cunoașterea profundă a acestor funcții esențiale și frecvent utilizate ale limbajului.

Fie că este vorba de backend, frontend sau chiar nave spațiale, JavaScript este omniprezent. Este, de asemenea, un limbaj extrem de adaptabil (ceea ce înseamnă că acceptă modele de programare funcționale, dar și structuri de clase clasice), iar asemănarea cu alte limbaje „de tip C” facilitează tranziția pentru programatorii din alte medii.

Dacă îți dorești să îmbunătățești abilitățile tale în JS, îți sugerez să înveți, să exersezi și să stăpânești următoarele funcții fundamentale disponibile în limbaj. Nu toate sunt strict „necesare” pentru a rezolva probleme, dar pot ușura sarcinile dificile în anumite situații și pot reduce volumul de cod pe care trebuie să-l scrii.

map()

Ar fi o greșeală să scriem un articol despre funcțiile importante JavaScript fără a menționa `map()`! 😆😆 Împreună cu `filter()` și `reduce()`, `map()` formează un trio esențial. Acestea sunt funcții pe care le vei folosi frecvent de-a lungul carierei tale, așa că merită să le acorzi atenția cuvenită. Să le explorăm pe rând, începând cu `map()`.

`map()` se numără printre funcțiile care cauzează cele mai multe dificultăți celor care învață JavaScript. De ce? Nu pentru că ar fi ceva intrinsec complicat, ci pentru că modul în care funcționează este un concept împrumutat din programarea funcțională. Și, deoarece nu suntem obișnuiți cu programarea funcțională – școlile și industria noastră fiind dominate de limbaje orientate pe obiecte – modul de operare al funcției pare neobișnuit sau chiar greșit pentru creierul nostru predispus la altceva.

JavaScript este mult mai funcțional decât orientat pe obiecte, deși versiunile moderne se străduiesc să ascundă acest lucru. Dar asta este o altă discuție pe care o vom aborda poate altă dată. 🤣 Așadar, să revenim la `map()`…

`map()` este o funcție foarte simplă; ea se aplică unei matrice și ne ajută să convertim fiecare element într-o formă diferită, rezultând o nouă matrice. Modul exact de conversie a unui element este specificat printr-o altă funcție, care, de obicei, este anonimă.

Cam asta este! Sintaxa poate necesita un timp de adaptare, dar în esență, asta facem într-o funcție `map()`. De ce am vrea să folosim `map()`? Depinde de obiectivul nostru. De exemplu, să presupunem că am înregistrat temperatura zilnică din ultima săptămână și am stocat-o într-o matrice simplă. Cu toate acestea, suntem informați că instrumentele nu au fost foarte precise și au raportat o temperatură cu 1,5 grade mai mică decât ar fi trebuit.

Putem face această corecție folosind funcția `map()` astfel:

const weeklyReadings = [20, 22, 20.5, 19, 21, 21.5, 23];

const correctedWeeklyReadings = weeklyReadings.map(reading => reading + 1.5);

console.log(correctedWeeklyReadings); // afișează [ 21.5, 23.5, 22, 20.5, 22.5, 23, 24.5 ]

Un alt exemplu, foarte relevant, vine din lumea React, unde crearea de liste de elemente DOM din matrice este un model frecvent; așadar, ceva de genul acesta este comun:

export default ({ products }) => {
    return products.map(product => {
        return (
            <div className="product" key={product.id}>
                <div className="p-name">{product.name}</div>
                <div className="p-desc">{product.description}</div>
            </div>
        );
    });
};

Aici, avem o componentă funcțională React care primește o listă de produse ca proprietăți. Din această listă (matrice), se construiește apoi o listă de „div”-uri HTML, transformând fiecare obiect produs în HTML. Obiectul original al produselor rămâne nemodificat.

Se poate argumenta că `map()` nu este altceva decât o buclă `for` avansată, și ai avea perfectă dreptate. Dar observă că, imediat ce faci această afirmație, mintea ta antrenată orientată pe obiect vorbește, în timp ce aceste funcții și logica lor provin din programarea funcțională, unde consecvența, concizia și eleganța sunt foarte apreciate. 🙂

filter()

`filter()` este o funcție extrem de utilă pe care o vei aplica frecvent în numeroase situații. După cum sugerează și numele, această funcție filtrează o matrice pe baza unor reguli/logici pe care le specifici și returnează o nouă matrice care conține elementele care respectă acele reguli.

Să folosim din nou exemplul cu vremea. Să presupunem că avem o matrice care conține temperaturile maxime pentru fiecare zi a săptămânii trecute; acum, dorim să aflăm câte dintre aceste zile au fost mai reci. Da, „mai rece” este un termen subiectiv, așadar vom presupune că ne interesează zilele în care temperatura a fost sub 20. Putem realiza acest lucru folosind funcția `filter()` astfel:

const weeklyReadings = [20, 22, 20.5, 19, 21, 21.5, 23];

const colderDays = weeklyReadings.filter(dayTemperature => {
    return dayTemperature < 20;
});

console.log("Numărul total de zile mai reci din săptămână a fost: " + colderDays.length); // 1

Reține că funcția anonimă pe care o trimitem către `filter()` trebuie să returneze o valoare booleană: `true` sau `false`. Acesta este modul în care `filter()` va ști dacă să includă sau nu acel element în matricea filtrată. Poți scrie orice complexitate de logică în această funcție anonimă; poți efectua apeluri API și citi intrările utilizatorilor și așa mai departe, atâta timp cât te asiguri că, în final, returnezi o valoare booleană.

Atenție: aceasta este o observație secundară pe care mă simt obligat să o ofer, bazându-mă pe experiența mea ca dezvoltator JavaScript. Fie din neglijență, fie din cauza unor concepte greșite, mulți programatori creează erori subtile în codul lor atunci când folosesc `filter()`. Să rescriem codul anterior pentru a introduce eroarea:

const weeklyReadings = [20, 22, 20.5, 19, 21, 21.5, 23];

const colderDays = weeklyReadings.filter(dayTemperature => {
    return dayTemperature < 20;
});

if(colderDays) {
    console.log("Da, au fost zile mai reci săptămâna trecută");
} else {
    console.log("Nu, nu au fost zile mai reci");
}

Observi ceva? Foarte bine dacă ai observat! Condiția `if` de la final verifică `colderDays`, care este de fapt o matrice! Vei fi surprins de cât de des oamenii fac această greșeală atunci când se grăbesc să respecte termenele limită sau când scriu cod într-o stare proastă (din orice motiv). Problema cu această condiție este că JavaScript este un limbaj ciudat și inconsistent în multe privințe, iar „adevărul” lucrurilor este una dintre ele. În timp ce `[] == true` returnează `false`, făcându-te să crezi că codul de mai sus nu este greșit, realitatea este că într-o condiție `if`, `[]` se evaluează la `true`! Cu alte cuvinte, codul pe care l-am scris nu va spune niciodată că nu au fost zile mai reci săptămâna trecută.

Soluția este foarte simplă, așa cum este prezentată în codul anterior celui de mai sus. Verificăm `colderDays.length`, care garantează că ne va oferi un număr întreg (zero sau mai mare) și, astfel, funcționează corect în comparațiile logice. Reține că `filter()` va returna întotdeauna, mereu, o matrice, fie goală, fie cu elemente, deci ne putem baza pe acest aspect și să scriem cu încredere comparațiile logice.

Am deviat puțin mai mult decât intenționam, dar erorile de acest fel merită subliniate în detaliu. Sper că nu vei fi victima ei și că vei economisi sute de ore de depanare! 🙂

reduce()

Dintre toate funcțiile din acest articol, precum și din biblioteca standard JavaScript, `reduce()` este printre primele care merită titlul de „confuză și neobișnuită”. Deși această funcție este extrem de importantă și generează cod elegant în multe situații, este evitată de majoritatea dezvoltatorilor JavaScript, care preferă să scrie cod mai explicit.

Motivul este că – și voi fi sincer aici! – `reduce()` este greu de înțeles, atât ca concept, cât și ca execuție. Când îi citești descrierea, o recitești de mai multe ori și totuși te îndoiești dacă ai înțeles corect; iar când o vezi în acțiune și încerci să vizualizezi cum funcționează, creierul tău se încurcă într-o mie de noduri! 🤭

Acum, nu te speria. Funcția `reduce()` nu este deloc la fel de complexă și intimidantă ca, să zicem, arborii B+ și algoritmii lor. Doar că acest tip de logică se întâlnește rar în rutina obișnuită de programare.

Așadar, după ce te-am speriat și apoi ți-am spus imediat să nu-ți faci griji, aș vrea în sfârșit să-ți arăt ce este această funcție și de ce am putea avea nevoie de ea.

După cum sugerează și numele, `reduce()` este folosită pentru a reduce ceva. Ceea ce reduce este o matrice, iar rezultatul reducerii este o singură valoare (număr, șir, funcție, obiect, orice). Într-un mod mai simplu, `reduce()` transformă o matrice într-o singură valoare. Reține că valoarea returnată de `reduce()` nu este o matrice, așa cum este cazul cu `map()` și `filter()`. Dacă ai înțeles acest aspect, deja ai parcurs jumătate din drum. 🙂

Acum, este destul de evident că, dacă vom transforma (reduce) o matrice, trebuie să specificăm logica necesară; iar bazându-te pe experiența ta ca dezvoltator JS, probabil ai ghicit deja că facem acest lucru printr-o funcție. Această funcție este ceea ce numim funcție reducătoare, care este primul argument al lui `reduce()`. Al doilea argument este o valoare inițială, cum ar fi un număr, un șir etc. (Voi explica în scurt timp ce rol are această „valoare inițială”).

Pe baza înțelegerii noastre de până acum, putem spune că un apel la `reduce()` arată astfel: `array.reduce(reducerFunction, startingValue)`. Acum să abordăm miezul întregului proces: funcția reducătoare. După cum am menționat, funcția reducătoare este cea care îi spune lui `reduce()` cum să convertească matricea într-o singură valoare. Aceasta primește două argumente: o variabilă care acționează ca un acumulator (nu-ți face griji, voi explica și acest lucru) și o variabilă pentru a stoca valoarea curentă.

Știu, știu… A fost multă terminologie pentru o singură funcție care nici măcar nu este obligatorie în JavaScript. 😝😝 Și de aceea oamenii evită `reduce()`. Dar dacă o înveți pas cu pas, nu numai că o vei înțelege, ci o vei aprecia pe măsură ce devii un dezvoltator mai bun.

Așadar, să revenim la subiect. „Valoarea inițială” transmisă lui `reduce()` este… ei bine, valoarea de start pentru calculul pe care vrei să-l efectuezi. De exemplu, dacă vei face înmulțiri în funcția reducătoare, o valoare inițială de 1 are sens; în plus, poți începe cu 0 și așa mai departe.

Acum să ne uităm la structura funcției reducătoare. O funcție reducătoare transmisă către `reduce()` are următoarea formă: `reducerFunction(accumulator, currentValue)`. „Acumulator” este doar un nume elegant pentru variabila care colectează și stochează rezultatul calculului; este ca și cum ai folosi o variabilă numită `total` pentru a aduna toate elementele dintr-o matrice folosind ceva de genul `total += arr[i]`. Exact așa se aplică funcția reducătoare din `reduce()`: acumulatorul este setat inițial la valoarea inițială pe care o specifici, apoi elementele matricei sunt vizitate unul câte unul, calculul este efectuat, iar rezultatul este stocat în acumulator și tot așa…

Așadar, ce este această „valoare curentă” într-o funcție reducătoare? Este același concept pe care l-ai vizualiza mental dacă te-aș ruga să parcurgi o matrice: ai lua o variabilă pentru a începe de la indexul zero și ai avansa cu un pas la un moment dat. În timp ce faci asta, dacă te-aș ruga să te oprești brusc, te-ai opri pe unul dintre elementele matricei, nu? Aceasta este ceea ce înțelegem prin valoarea curentă: este valoarea variabilei folosită pentru a reprezenta elementul matricei care este în prezent luat în considerare (gândește-te la o buclă care parcurge o matrice dacă te ajută).

Având toate acestea în vedere, este timpul să vedem un exemplu simplu și să vedem cum tot acest limbaj special se reunește într-un apel real `reduce()`. Să presupunem că avem o matrice care conține primele n numere naturale (1, 2, 3… n) și ne interesează să găsim factorialul lui n. Știm că pentru a găsi n!, trebuie pur și simplu să înmulțim toate numerele, ceea ce ne conduce la această implementare:

const numbers = [1, 2, 3, 4, 5];
const factorial = numbers.reduce((acc, item) => acc * item, 1);
console.log(factorial); // 120

Se întâmplă multe în aceste trei linii de cod, așa că să le analizăm una câte una în contextul discuției (foarte lungi) pe care am avut-o până acum. După cum este evident, `numbers` este matricea care conține toate numerele pe care vrem să le înmulțim. Apoi, uită-te la apelul `numbers.reduce()`, care specifică faptul că valoarea inițială pentru `acc` ar trebui să fie 1 (pentru că nu influențează și nu distruge nicio înmulțire). Apoi, verifică corpul funcției reducătoare, `(acc, item) => acc * item`, care indică pur și simplu că valoarea returnată pentru fiecare iterație peste matrice ar trebui să fie elementul respectiv înmulțit cu ceea ce se află deja în acumulator. Iterația și stocarea efectivă a înmulțirii în mod explicit în acumulator sunt ceea ce se întâmplă în culise și este unul dintre cele mai importante motive pentru care `reduce()` reprezintă o problemă pentru dezvoltatorii JavaScript.

De ce să folosești `reduce()`?

Aceasta este o întrebare foarte bună și, ca să fiu sincer, nu am un răspuns clar. Orice face `reduce()` poate fi făcut și cu bucle, `forEach()` etc. Cu toate acestea, aceste tehnici generează un volum de cod mult mai mare, ceea ce îl face dificil de citit, mai ales dacă te grăbești. Apoi, mai este și preocuparea pentru imuabilitate: cu `reduce()` și funcții similare, poți fi sigur că datele tale originale nu au fost modificate; acest lucru elimină categorii întregi de erori, în special în aplicațiile distribuite.

În cele din urmă, `reduce()` este mult mai flexibilă, în sensul că acumulatorul poate fi un obiect, o matrice sau chiar o funcție, dacă este nevoie; același lucru este valabil și pentru valoarea inițială și pentru alte părți ale apelului de funcție – aproape orice poate intra și aproape orice poate ieși, deci există o flexibilitate extraordinară în conceperea codului reutilizabil.

Dacă încă nu ești convins, e perfect în regulă; comunitatea JavaScript este puternic divizată în privința „conciziei”, „eleganței” și „puterii” lui `reduce()`, așa că nu este nicio problemă dacă nu-l folosești. 🙂 Dar asigură-te că analizezi câteva exemple utile înainte de a decide să-l ignori complet.

some()

Să presupunem că ai o listă de obiecte, fiecare obiect reprezentând o persoană. Vrei să afli dacă în matrice există persoane care au peste 35 de ani. Reține că nu trebuie să numeri câte astfel de persoane sunt, cu atât mai puțin să obții o listă a acestora. Ceea ce spunem aici este echivalent cu „una sau mai multe” sau „cel puțin una”.

Cum faci acest lucru?

Da, ai putea crea o variabilă de tip flag și ai putea parcurge matricea pentru a rezolva această problemă astfel:

const persons = [
    {
        name: 'Persoana 1',
        age: 32
    },
    
    {
        name: 'Persoana 2',
        age: 40
    },
];

let foundOver35 = false;

for (let i = 0; i < persons.length; i ++) {
    if(persons[i].age > 35) {
        foundOver35 = true;
        break;
    }
}

if(foundOver35) {
    console.log("Da, sunt câteva persoane aici!")
}

Problema? Codul este prea asemănător cu C sau Java, după părerea mea. „Verbos” este un alt cuvânt care îmi vine în minte. Un dezvoltator JS experimentat s-ar putea gândi la „urât”, „oribil” etc. 😝 Și pe bună dreptate, aș argumenta. O modalitate de a îmbunătăți acest cod ar fi să folosești ceva de genul `map()`, dar chiar și atunci soluția este un pic neplăcută.

Se pare că avem o funcție destul de utilă numită `some()` deja disponibilă în limbajul de bază. Această funcție se aplică matricelor și acceptă o funcție personalizată de „filtrare”, returnând o valoare booleană `true` sau `false`. În esență, face ceea ce am încercat să facem în ultimele minute, doar foarte concis și elegant. Iată cum o putem folosi:

const persons = [
    {
        name: 'Persoana 1',
        age: 32
    },
    
    {
        name: 'Persoana 2',
        age: 40
    },
];

if(persons.some(person => {
    return person.age > 35
})) {
    console.log("Am găsit câteva persoane!")
}

Aceeași intrare, același rezultat ca înainte; dar observă reducerea masivă de cod! Observă, de asemenea, cât de mult se reduce sarcina cognitivă, deoarece nu mai trebuie să analizăm codul linie cu linie ca și cum am fi noi înșine interpretorul! Acum, codul se citește aproape ca un limbaj natural.

every()

Similar cu `some()`, avem o altă funcție utilă numită `every()`. După cum probabil ai ghicit, și aceasta returnează o valoare booleană în funcție de dacă toate elementele din matrice trec testul specificat. Bineînțeles, testul de trecut este furnizat printr-o funcție anonimă de cele mai multe ori. Te voi scuti de neplăcerea de a vedea cum ar arăta o versiune naivă a codului, așa că iată cum este folosit `every()`:

const entries = [
    {
        id: 1
    },
    
    {
        id: 2
    },
    
    {
        id: 3  
    },
];

if(entries.every(entry => {
    return Number.isInteger(entry.id) && entry.id > 0;
})) {
    console.log("Toate intrările au un id valid")
}

După cum este evident, codul verifică toate obiectele din matrice pentru o proprietate `id` validă. Definiția termenului „valid” depinde de contextul problemei, dar după cum poți vedea, în acest cod am considerat numere întregi nenegative. Încă o dată, observăm cât de simplu și elegant este codul de citit, ceea ce este scopul principal al acestei funcții (și al altora similare).

includes()

Cum verifici existența subșirurilor și a elementelor matricei? Ei bine, dacă ești ca mine, apelezi repede la `indexOf()` și apoi cauți în documentație pentru a te familiariza cu valorile posibile de returnare. Este o neplăcere considerabilă, iar valorile returnate sunt dificil de reținut (rapid – ce înseamnă un proces care returnează 2 pentru sistemul de operare?).

Dar există o alternativă elegantă pe care o putem folosi: `includes()`. Utilizarea sa este la fel de simplă ca numele, iar codul rezultat este extrem de plăcut. Reține că potrivirea efectuată de `includes()` este sensibilă la majuscule, dar cred că la asta ne așteptăm oricum intuitiv. Și acum, este timpul pentru niște cod!

const numbers = [1, 2, 3, 4, 5];
console.log(numbers.includes(4));
const name = "Ankush";
console.log(name.includes('ank')); // false, deoarece prima literă este minusculă
console.log(name.includes('Ank')); // true, așa cum ne așteptam

Cu toate acestea, nu te aștepta la prea multe de la această metodă umilă:

const user = {a: 10, b: 20};
console.log(user.includes('a')); // va da eroare, deoarece obiectele nu au o metodă "includes"

Nu poate cerceta în interiorul obiectelor, deoarece pur și simplu nu este definită pentru obiecte. Dar, hei, știm că funcționează pe matrice, așa că poate putem face câteva trucuri aici… 🤔.

const persons = [{name: 'Phil'}, {name: 'Jane'}];
persons.includes({name: 'Phil'});

Așadar, ce se întâmplă când rulezi acest cod? Nu dă eroare, dar rezultatul este și el dezamăgitor: `false`. 😫😫 De fapt, acest lucru are legătură cu obiectele, pointerii și modul în care JavaScript vede și gestionează memoria, care este un univers aparte. Dacă dorești să aprofundezi subiectul, nu ezita să faci pasul (poți începe aici), dar eu mă opresc chiar aici.

Putem face ca codul de mai sus să funcționeze corect dacă îl rescriem după cum urmează, dar în acest moment devine mai mult sau mai puțin o glumă, după părerea mea:

const phil = {name: 'Phil'};
const persons = [phil, {name: 'Jane'}];
persons.includes(phil); // true

Totuși, demonstrează că putem face `includes()` să funcționeze și pe obiecte, așa că bănuiesc că nu este un dezastru total. 😄

slice()

Să presupunem că avem un șir și te rog să returnezi o porțiune a acestuia care începe cu „r” și se termină cu „z” (caracterele reale nu contează). Cum ai aborda acest lucru? Poate ai crea un nou șir și l-ai folosi pentru a stoca toate caracterele necesare și apoi le-ai returna. Sau, dacă ești ca majoritatea programatorilor, mi-ai da în schimb doi indici de matrice: unul care indică începutul subșirului, iar celălalt care marchează sfârșitul.

Ambele abordări sunt bune, dar există un concept numit feliere care oferă o soluție elegantă în astfel de situații. Din fericire, nu există nicio teorie abstractă de urmat; felierea înseamnă exact ceea ce spune – crearea unui șir/matrice mai mic din cel dat, exact cum creăm felii de fructe. Să vedem ce vreau să spun, cu ajutorul unui exemplu simplu:

const headline = "Și în emisiunea specială de azi, îl avem ca invitat pe cel pe care l-am așteptat cu toții!";
const startIndex = headline.indexOf('invitat');
const endIndex = headline.indexOf('așteptat');
const newHeadline = headline.slice(startIndex, endIndex);
console.log(newHeadline); // invitat pe cel pe care l-am

Când folosim `slice()`, oferim doi indici pentru JavaScript – unul de unde dorim să începem felierea și celălalt unde vrem să ne oprim. Problema cu `slice()` este că indexul final nu este inclus în rezultatul final, motiv pentru care vedem că lipsește cuvântul „așteptat” din noul titlu din codul de mai sus.

Concepte precum felierea sunt mai proeminente în alte limbaje, în special în Python. Dacă îi întrebi pe acești dezvoltatori, vor spune că nu-și pot imagina viața fără această funcționalitate și, pe bună dreptate, atunci când limbajul oferă o sintaxă foarte elegantă pentru feliere.

Felierea este elegantă și extrem de convenabilă și nu există niciun motiv să nu o folosești. De asemenea, nu este doar un artificiu de sintaxă cu o penalizare de performanță, deoarece creează copii superficiale ale matricei/șirului original. Pentru dezvoltatorii JavaScript, le-aș recomanda să se familiarizeze cu `slice()` și să-l adauge în arsenalul lor!

splice()

Metoda `splice()` sună ca un văr al lui `slice()` și, într-un fel, putem argumenta că așa este. Ambele creează noi matrice/șiruri din cele originale, cu o mică, dar importantă diferență – `splice()` elimină, modifică sau adaugă elemente, dar modifică matricea originală. Această „distrugere” a matricei originale poate crea probleme majore dacă nu ești atent sau nu înțelegi copiile profunde și referințele. Mă întreb ce i-a împiedicat pe dezvoltatori să folosească aceeași abordare ca pentru `slice()` și să lase matricea originală intactă, dar cred că putem fi mai înțelegători cu un limbaj creat în doar zece zile.

În ciuda plângerilor mele, să vedem cum funcționează `splice()`. Voi arăta un exemplu în care eliminăm câteva elemente dintr-o matrice, deoarece aceasta este cea mai comună utilizare pe care o vei întâlni pentru această metodă. De asemenea, mă voi abține să ofer exemple de adăugare și inserare, deoarece acestea pot fi căutate ușor și sunt, de asemenea, simple.

const items = ['ouă', 'lapte', 'brânză', 'pâine', 'unt'];
items.splice(2, 1);
console.log(items); // [ 'ouă', 'lapte', 'pâine', 'unt' ]

Apelul la `splice()` de mai sus specifică: începe de la indexul 2 (al treilea loc, adică) al matricei și elimină un element. În matricea dată, „brânza” este al treilea element, așa că este eliminată din matrice, iar matricea `items` este scurtată, așa cum ne așteptăm. Apropo, elementele eliminate sunt returnate de `splice()` sub forma unei matrice, așa că, dacă am fi dorit, am fi putut stoca „brânza” într-o variabilă.

Din experiența mea, `indexOf()` și `splice()` au o sinergie puternică – găsim indexul unui element și apoi îl eliminăm din matricea dată. Cu toate acestea, reține că nu este întotdeauna cea mai eficientă metodă, iar de multe ori folosirea cheilor unui obiect (echivalentul unei hărți hash) este mult mai rapidă.

shift()

`shift()` este o metodă utilă de sortare și este folosită pentru a elimina primul element dintr-o matrice. Observă că același lucru se poate face cu `splice()`, dar `shift()` este puțin mai ușor de reținut și intuitiv atunci când tot ce trebuie să faci este să tai primul element.

const items = ['ouă', 'lapte', 'brânză', 'pâine', 'unt'];
items.shift()
console.log(items); // [ 'lapte', 'brânză', 'pâine', 'unt' ]

unshift()

La fel cum `shift()` elimină primul element dintr-o matrice, `unshift()` adaugă un nou element la începutul matricei. Utilizarea sa este la fel de simplă și concisă:

const items = ['ouă', 'lapte'];
items.unshift('pâine')
console.log(items); // [ 'pâine', 'ouă', 'lapte' ]

Acestea fiind spuse, nu mă pot abține și îi avertizez pe cei noi în domeniu: spre deosebire de metodele populare `push()` și `pop()`, `shift()` și `unshift()` sunt extrem de ineficiente (din cauza modului în care funcționează algoritmii de bază). Așadar, dacă operezi cu matrice mari (de exemplu, peste 2000 de elemente), prea multe apeluri ale acestor funcții pot încetini aplicația.

fill()

Uneori, trebuie să schimbi mai multe elemente cu o singură valoare sau chiar să „resetezi” întreaga matrice, ca să spunem așa. În aceste situații, `fill()` te scutește de bucle și erori de tip off-by-one. Poate fi folosit pentru a înlocui o parte sau întreaga matrice cu valoarea specificată. Să vedem câteva exemple:

const heights = [1, 2, 4, 5, 6, 7, 1, 1];
heights.fill(0);
console.log(heights); // [0, 0, 0, 0, 0, 0, 0